根据 JSON 单元格的内容删除行

问题描述 投票:0回答:1

我有一个包含 JSON 列的表。 JSON 列内的数据组织如下:

[{"name":"Apple","short_name":"A"},{"name":"Banana","short_name":"B"}]

大多数行只有一个名称/短名称,但有些行(如上面的示例)有多个名称/短名称。我需要做的是从我的选择中删除 JSON 单元格中包含 Kiwi 的所有行。

我尝试使用

WHERE JSON_CONTAINS(persons.fruits, '"Kiwi"', '$')
,也尝试过
JSON_ARRAY_CONTAINS(JSON_EXTRACT_ARRAY(persons.fruits, '$'), 'Kiwi')
并得到两个函数均未找到该函数的错误。我可能误用了这些功能,这是我第一次尝试使用它们。我该怎么办?

sql json google-bigquery
1个回答
0
投票

您必须取消数组的嵌套并在 JSON 中搜索值。有多种方法,但它们都涉及查询每行数组中可用的不同值。

以您提供的结构为例,下面的查询将过滤掉其中一个数组记录中名称为“Kiwi”的行:

WITH base_data AS (
  SELECT PARSE_JSON('[{"name":"Apple","short_name":"A"},{"name":"Banana","short_name":"B"}]') as fruits_array
  
  UNION ALL

  SELECT PARSE_JSON('[{"name":"Kiwi","short_name":"K"},{"name":"Banana","short_name":"B"}]') as fruits_array

  UNION ALL

  SELECT PARSE_JSON('[{"name":"Apple","short_name":"A"},{"name":"Kiwi","short_name":"K"}]') as fruits_array
)

select *
from base_data
where 'Kiwi' not in (SELECT JSON_VALUE(fruit_json.name) FROM UNNEST(JSON_QUERY_ARRAY(fruits_array)) fruit_json)

假设您的值严格为 JSON,则此查询将起作用。

Input

Output

其工作原理:

  • 对于每一行,我们在子查询中计算每条记录的“name”键中的可用值列表
  • 使用 where 语句,然后过滤掉可用值列表中存在值“Kiwi”的任何行,从而仅保留不具有值“Kiwi”的行

另一种可能的解决方案是将 JSON 视为纯字符串并查找“Kiwi”的实际字符串 - 但这种方法并不完全安全,我不建议严重依赖它:

WITH base_data AS (
  SELECT PARSE_JSON('[{"name":"Apple","short_name":"A"},{"name":"Banana","short_name":"B"}]') as fruits_array
  
  UNION ALL

  SELECT PARSE_JSON('[{"name":"Kiwi","short_name":"K"},{"name":"Banana","short_name":"B"}]') as fruits_array

  UNION ALL

  SELECT PARSE_JSON('[{"name":"Apple","short_name":"A"},{"name":"Kiwi","short_name":"K"}]') as fruits_array
)

select *
from base_data
where TO_JSON_STRING(fruits_array) NOT LIKE '%Kiwi%'
© www.soinside.com 2019 - 2024. All rights reserved.