如何在BigQuery中对嵌套层级内的字段使用as重命名
解决BigQuery嵌套字段重命名问题
方法1:用SELECT * REPLACE保留结构,仅替换目标字段
这种方式不用手动列出所有字段,只针对要修改的嵌套层级做替换,原表其他字段会自动保留,适合字段较多的场景。
比如要把person.details.firstName改成person.details.first_name,可以这么写:
SELECT * REPLACE( (SELECT AS STRUCT details.* REPLACE( firstName AS first_name ) FROM UNNEST([person.details]) AS details ) AS details ) FROM your_table
如果是更深层级的嵌套(比如person.details.contact.phoneNumber改phone_number),可以嵌套使用这个逻辑:
SELECT * REPLACE( (SELECT AS STRUCT details.* REPLACE( (SELECT AS STRUCT contact.* REPLACE( phoneNumber AS phone_number ) FROM UNNEST([details.contact]) AS contact ) AS contact ) FROM UNNEST([person.details]) AS details ) AS details ) FROM your_table
方法2:利用Dataform的JS能力批量处理
如果有大量驼峰命名的嵌套字段要统一改成下划线格式,用Dataform的JavaScript遍历字段结构,自动生成重命名SQL更高效。
示例SQLX代码:
config { type: "table" } {% set source_table = ref("your_source_table") %} {% set columns = get_columns(source_table) %} SELECT {% for col in columns %} {% if col.name == 'person' %} (SELECT AS STRUCT {% for nested_col in col.fields %} {% if nested_col.name == 'details' %} (SELECT AS STRUCT {% for detail_col in nested_col.fields %} {{ detail_col.name }} AS {{ snakecase(detail_col.name) }}{% if not loop.last %},{% endif %} {% endfor %} ) AS details{% if not loop.last %},{% endif %} {% else %} {{ nested_col.name }} AS {{ nested_col.name }}{% if not loop.last %},{% endif %} {% endif %} {% endfor %} ) AS person{% if not loop.last %},{% endif %} {% else %} {{ col.name }} AS {{ col.name }}{% if not loop.last %},{% endif %} {% endif %} {% endfor %} FROM {{ source_table }}
这里用Dataform内置的snakecase函数自动把驼峰转成下划线,遍历字段结构时只处理目标嵌套层级,其他字段原样保留。
方法3:手动构造STRUCT(适合少量字段修改)
如果要改的嵌套字段不多,直接构造STRUCT保留其他字段也可行:
SELECT STRUCT( STRUCT( person.details.firstName AS first_name, person.details.lastName, -- 保留原有字段名 person.details.age -- 保留原有字段名 ) AS details, person.address, -- 保留person下的其他嵌套字段 person.id -- 保留person下的其他字段 ) AS person, other_column1, other_column2 FROM your_table
内容的提问来源于stack exchange,提问作者afx
相关产品推荐
相关产品推荐

