从 BigQuery 中的 JSON 数组中提取多个值

Posted

技术标签:

【中文标题】从 BigQuery 中的 JSON 数组中提取多个值【英文标题】:Extract multiple values from an array in JSON in BigQuery 【发布时间】:2021-09-30 04:11:35 【问题描述】:

我的数据库表中有一个 JSON,如下表所示,假设列包含一个名为收藏夹的 JSON 文件。


    "info": 
        "music": ["Year":2021,"Name":"Stay","Singer":"Justin Bieber",
                  "Year":2015,"Name":"Love Yourself","Singer":"Justin Bieber",
                  "Year":2003,"Name":"Crazy In Love","Singer":"Beyonce"
                 ],
        "movie": ["Year":2018,"Name":"Green Book","Director":"Peter Farrelly",
                  "Year":2007,"Name":"Lust, Caution","Director":"Ang Lee"
                 ]
             


I wanted to select all values from tags and my expected table would be like as following:

-----------------------------------------------------------------------------
|             Name                    |                      Singer         |
----------------------------------------------------------------------------
|   Stay,Love Yourself,Crazy In Love  |  Justin Bieber,Justin Bieber,Beyonce|
-----------------------------------------------------------------------------

我已经知道如何使用 JSON_QUERY(json_col,'$.info.music[0].Name') 获取数组中的第一个值,但我想将所有名称或歌手提取到一个单独的列中,有些数组可能有多个项目。有人有什么建议吗?

【问题讨论】:

"movie" 之前是否缺少逗号? 是的,感谢您的关注! 【参考方案1】:

考虑以下方法

select 
  array(select json_extract_scalar(x, '$.Name') from unnest(json_extract_array(json_col, '$.info.music') || json_extract_array(json_col, '$.info.movie')) x) Name,
  array(select json_extract_scalar(x, '$.Singer') from unnest(json_extract_array(json_col, '$.info.music')) x) Singer
from data      

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

我刚刚意识到 - 你想要逗号分隔的列表 - 所以请考虑下面

select 
  (select string_agg(json_extract_scalar(x, '$.Name')) from unnest(json_extract_array(json_col, '$.info.music') || json_extract_array(json_col, '$.info.movie')) x) Name,
  (select string_agg(json_extract_scalar(x, '$.Singer')) from unnest(json_extract_array(json_col, '$.info.music')) x) Singer
from data     

有输出

【讨论】:

json_extract_scalar() 中的 x 是什么? 只是 unnest() 的别名 - 请参阅相应行的编辑。名称无关紧要,可以是任何有效名称,例如 abc 或 xyz 或其他任何名称 1) json_extract_array - 返回 jsons 数组 2)unnest() 一个一个返回该数组的元素并被别名为 x - 所以 x 本质上也是 json 3) 现在 json_extract_scalar - 从 x 中提取无论 xpath 是什么:希望这有助于理解解决方案的逻辑 :o) 非常感谢!我发现第一种方法效果更好。但我有一个关于 COUNT() 的问题。假设我会统计听不同歌曲的人数,因为一行有多个子行,这会影响按名称计算的 count(*) 组吗? 很高兴它有帮助。如果有帮助,请考虑对答案进行投票 - 这在 SO 上同样重要,并且 激励我们回答您的下一个问题 :o)【参考方案2】:

另一个溶胶。如果您不想聚合,可以使用 ARRAY_TO_STRING。

with data as
(
select
    """
    
"info": 
        "music": ["Year":2021,"Name":"Stay","Singer":"Justin Bieber",
                  "Year":2015,"Name":"Love Yourself","Singer":"Justin Bieber",
                  "Year":2003,"Name":"Crazy In Love","Singer":"Beyonce"
                 ],
        "movie": ["Year":2018,"Name":"Green Book","Director":"Peter Farrelly",
                  "Year":2007,"Name":"Lust, Caution","Director":"Ang Lee"
                 ]
             

""" as _json
)

select array_to_string(
    array(
    select  json_extract_scalar(x,"$.Name")
    from  data,  
          unnest(json_extract_array(_json,"$.info.music")) as x
),"," 
) as Name, array_to_string(
    array(
      select  json_extract_scalar(x,"$.Singer")
    from  data,  
        unnest(json_extract_array(_json,"$.info.music")) as x
),","
) as Singer

结果

【讨论】:

以上是关于从 BigQuery 中的 JSON 数组中提取多个值的主要内容,如果未能解决你的问题,请参考以下文章

从 BigQuery 数据 JSON 中的数组中提取索引值

Bigquery:从 json 数组中提取数据

Bigquery:是不是有一种 json 路径方法可以仅从具有动态键的 json 数组中提取值?

从 Google Ads BigQuery 数据传输中提取/取消嵌套数组

Google BigQuery SQL:从 JSON(列表和数组)中提取数据到列中

选择/提取 JSON 元素时的高效 BigQuery