从 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 路径方法可以仅从具有动态键的 json 数组中提取值?
从 Google Ads BigQuery 数据传输中提取/取消嵌套数组