有没有一种优雅的方法可以将 BQ 嵌套字段转换为 key:value JSON?

Posted

技术标签:

【中文标题】有没有一种优雅的方法可以将 BQ 嵌套字段转换为 key:value JSON?【英文标题】:Is there an elegant way to turn a BQ nested field in to a key:value JSON? 【发布时间】:2021-01-23 19:34:56 【问题描述】:

我希望将 event_params 嵌套 BQ 字段转换为 JSON 字段的选项?

我想要的输出应该是这样的:

"sessionId":123456789,"version":"1.005"

【问题讨论】:

【参考方案1】:

考虑下面

select *, (
  select '' || string_agg(format('%s:%s',
    json_extract(kv, '$.key'),
    json_extract(kv, '$.string_value')
  )) || ''
  from unnest(json_extract_array(to_json_string(event_params))) kv
) json
from `project.dataset.table`    

如果应用于您问题中的样本数据 - 输出是

更新:我意识到您更改/修复了数据样本 - 请参阅下面的更新查询

select *, (
  select '' || string_agg(format('%s:%s',
    json_extract(kv, '$.key'),
    json_extract(kv, '$.value.string_value')
  )) || ''
  from unnest(json_extract_array(to_json_string(event_params))) kv
) json
from `project.dataset.table`

有输出

【讨论】:

【参考方案2】:

我制作了一个版本,您可以在其中以适当的格式在 JSON 对象中定义数字字段,并且您可以过滤某些键以最终出现在 JSON 对象中:

with t as (
    -- fake example data with same format
    select * from unnest([
        struct([
            struct('session_id' as key, struct('123' as string_value) as value), 
                  ('timestamp', struct('1234567')), 
                  ('version', struct('2.23.65'))
                ] as event_params)
        ,struct([struct('session_id',struct('645')),('timestamp',struct('7653365')),('version',struct('3.675.34'))])
    ])
    
)

-- actual query
select 
   event_params,      -- original data for comparison
   format(' %s ',   -- for each row create one json object:
    (select           -- string_agg will return one string with all key-value pairs comma-separated
         string_agg(  -- within aggregation create key-value pairs
             if(key in ('timestamp','session_id'),            -- if number fields 
                format('"%s" : %s',key,value.string_value),   -- then number format
                format('"%s" : "%s"',key,value.string_value)) -- else string format
             , ', ')
     from unnest(event_params)   -- unnest turns array into a little table per row, so we can run SQL on it
     where key in ('session_id','version')   -- filter for certain keys
    )   -- subquery end
   ) as json
from t

【讨论】:

太棒了!非常感谢你,马丁!

以上是关于有没有一种优雅的方法可以将 BQ 嵌套字段转换为 key:value JSON?的主要内容,如果未能解决你的问题,请参考以下文章

BQ数组查找:类似于NTH,但基于索引,而不是位置

将嵌套的 json 导入为具有多个嵌套的表

一种将当前日期时间转换为 ISO 8601 格式的优雅方法 [重复]

有没有一种优雅的方法可以用 XSLT 添加多个 HTML 类?

有没有一种优雅的方法可以在使用 Guava 转换集合时删除空值?

在 Java 中将基元数组转换为容器数组