BigQuery中UNNEST STRUCT时无需内部加AS自定义列名的方案
结论
你设想的UNNEST(...) AS (a,b,c,d,e)写法在BigQuery中不支持,执行会返回语法错误。BigQuery不允许在数组展开的表别名后直接按位置定义列名。
适配动态生成SQL场景的可行方案
不需要在STRUCT内部逐个字段加AS别名,以下两种方案都可以实现自定义列名的需求,且代码生成逻辑简单:
- 方案1:使用
VALUES子句构造常量表,支持在表别名后统一按位置声明列名,完全匹配你想要的写法逻辑
这是最贴合需求的写法,不需要给单个字段加别名,只需要在构造完所有行数据后,统一在末尾追加列名定义即可,示例代码:
用Python动态生成时,只需要把每行数据转成逗号分隔的元组字符串拼接在VALUES后,最后按列的顺序把列名拼在SELECT * FROM ( VALUES (1, 3.07766, 6.31371, 12.7062, 63.65600), (2, 1.88562, 2.91999, 4.30265, 9.92482), (3, 1.63774, 2.35336, 3.18243, 5.84089) ) AS t(a, b, c, d, e)AS t(...)里即可,不需要遍历每个字段加别名,拼接成本极低,生成的SQL可以直接用于MERGE语句。 - 方案2:保留原有UNNEST+STRUCT的写法,在外层SELECT中统一对默认生成的
f0_、f1_...字段做别名映射
如果更习惯原有数组构造的写法,不需要修改STRUCT内部的内容,只需要在外层统一做别名转换即可,示例:
这种写法的动态生成逻辑也很简单:列名和默认的SELECT f0_ AS a, f1_ AS b, f2_ AS c, f3_ AS d, f4_ AS e FROM UNNEST([ STRUCT(1, 3.07766, 6.31371, 12.7062, 63.65600), (2, 1.88562, 2.91999, 4.30265, 9.92482), (3, 1.63774, 2.35336, 3.18243, 5.84089) ])fN_字段是按位置一一对应的,只需要按顺序生成f0_ AS 列名1, f1_ AS 列名2...的映射段即可,同样不需要修改STRUCT内部的字段。
性能提示
如果构造的临时表数据量超过1万行,优先用方案2的UNNEST+STRUCT写法,解析效率比VALUES子句更高;数据量较小时两种写法性能没有差异。
内容的提问来源于stack exchange,提问作者Andrii Kusch
相关产品推荐
相关产品推荐

