简体   繁体   English

如何从 Big Query 中的 JSON 数组中提取特定字段?

[英]How do you extract a specific field from a JSON array in Big Query?

I currently have a JSON array that looks like this in Big Query:我目前有一个 JSON 数组,在 Big Query 中看起来像这样:

[{"name":"","username":null},{"name":"Jimmy Dean","username":"iamjc"},{"name":"Ben Simmons","username":"bens"}]

I want to create a column that just has a list of username values.我想创建一个只有用户名值列表的列。 For the example above, I would like the column to display对于上面的示例,我希望该列显示

"iamjc", "bens"

I've tried using json_extract_scalar with unnest but it is throwing an error because of the null value.我试过将 json_extract_scalar 与 unnest 一起使用,但由于 null 值而引发错误。

CREATE TEMP FUNCTION json2array(json STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
  return JSON.parse(json).map(x=>JSON.stringify(x));
""";
select
g.created_at as message_sent,
username as sender,
members as original_members,
ARRAY(SELECT JSON_EXTRACT_SCALAR(x, '$.username')
  FROM UNNEST(json2array(JSON_EXTRACT(members, '$'))) x
  ) AS members
from `table_1` g
join `table_2` u
 on u._id = json_value(g.user, "$.id") and is_staff is false
where g.type = 'message.new'
order by 1 desc

The error on output is this: output 上的错误是这样的:

Array cannot have a null element; error in writing field members

Would anyone know how to get this desired output?有人知道如何获得这个所需的 output 吗?

Just add WHERE clause as in below example只需添加WHERE子句,如下例所示

  ARRAY(SELECT JSON_EXTRACT_SCALAR(x, '$.username')
  FROM UNNEST(json2array(JSON_EXTRACT(members, '$'))) x
  WHERE NOT JSON_EXTRACT_SCALAR(x, '$.username') IS NULL
  ) AS members  

Or, use below option (in which case you don't even need json2array UDF或者,使用下面的选项(在这种情况下你甚至不需要json2array UDF

  array(select json_extract_scalar(x, '$.username')
  from unnest(json_extract_array(members)) x
  where not json_extract_scalar(x, '$.username')is null
  ) as members    

if applied to dummy data as in your question如果应用于您的问题中的虚拟数据

with your_table as (
  select '[{"name":"","username":null},{"name":"Jimmy Dean","username":"iamjc"},{"name":"Ben Simmons","username":"bens"}]' members
)
select *,
  array(select json_extract_scalar(x, '$.username')
  from unnest(json_extract_array(members)) x
  where not json_extract_scalar(x, '$.username')is null
  ) as members
from your_table             

output is output 是

在此处输入图像描述

Specifying IGNORE NULLS when you create an array would be helpful.在创建数组时指定IGNORE NULLS会很有帮助。 Refer to below query.请参阅以下查询。

WITH sample_data AS (
  SELECT '[{"name":"","username":null},{"name":"Jimmy Dean","username":"iamjc"},{"name":"Ben Simmons","username":"bens"}]' AS members
)
SELECT ARRAY_AGG(JSON_VALUE(m, '$.username') IGNORE NULLS) AS members 
  FROM sample_data, UNNEST(JSON_QUERY_ARRAY(members, '$')) m;

+------+---------+
| Row  | members |
+------+---------+
| 1    | iamjc   |
|      | benj    |
+------+---------+

And since JSON_EXTRACT_* functions became a legacy, better use new JSON functions:由于JSON_EXTRACT_*函数成为遗留问题,最好使用新的 JSON 函数:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM