如何在BigQuery函数中用字符串作为列名获取对应值
解决BigQuery函数中动态列名取值的问题
你的问题核心在于:当你把字符串参数column直接放进SELECT语句时,BigQuery会把它当作字符串字面量处理,而不是解析成列名。又因为标量函数不支持EXECUTE IMMEDIATE,所以动态SQL这条路走不通。好在我们可以用UNPIVOT转换表结构的方式来绕开这个限制,具体方案如下:
方案一:在函数内直接使用UNPIVOT
我们可以通过UNPIVOT把原表的列转换为键值对形式(列名作为col,列值作为value),然后通过匹配传入的列名字符串来获取对应的值。改写后的函数如下:
CREATE OR REPLACE FUNCTION METADATA.GET_VALUE(column_name STRING, row_number INT64) AS ( SELECT value FROM WORK.temp UNPIVOT (value FOR col IN ( TXCAMP10, TXCAMP20, -- 这里列出你需要支持的所有列名 -- 如果有其他需要访问的列,都要在这里添加 )) WHERE rownumber = row_number AND col = column_name );
调用示例
执行SELECT METADATA.GET_VALUE("TXCAMP10", 149);时,函数会先把WORK.temp的指定列转成键值对行,然后筛选出行号为149且列名等于TXCAMP10的记录,返回对应的value值,也就是你想要的列数据。
方案二:预先创建转置视图(更易维护)
如果你的WORK.temp表列比较多,或者列会频繁更新,每次修改函数里的UNPIVOT列表会很麻烦。这时可以先创建一个转置后的视图,再让函数查询这个视图:
1. 创建转置视图
CREATE OR REPLACE VIEW WORK.temp_unpivoted AS SELECT rownumber, col, value FROM WORK.temp UNPIVOT (value FOR col IN ( TXCAMP10, TXCAMP20, -- 列出所有需要访问的列 -- 其他列... ));
2. 改写函数查询视图
CREATE OR REPLACE FUNCTION METADATA.GET_VALUE(column_name STRING, row_number INT64) AS ( SELECT value FROM WORK.temp_unpivoted WHERE rownumber = row_number AND col = column_name );
这样后续列有变动时,只需要更新temp_unpivoted视图即可,函数不需要修改,维护成本更低。
注意事项
UNPIVOT里必须显式列出所有需要支持的列,BigQuery目前不支持动态自动识别所有列(除非结合INFORMATION_SCHEMA生成动态SQL,但那只能在脚本或存储过程里用,函数还是不行)。- 如果你的列类型不一致,
UNPIVOT会自动把value类型转换为所有列的公共类型(比如字符串),如果需要保留原类型,可以考虑分类型处理,或者在函数里做类型转换。
内容的提问来源于stack exchange,提问作者Kedar Kodgire
相关产品推荐
相关产品推荐

