【问题标题】:Standard SQL - multiple rows from an ARRAY of STRUCT标准 SQL - 来自 STRUCT 数组的多行
【发布时间】:2020-05-02 09:12:13
【问题描述】:

我有一个类似于以下的 JSON 结构:

{"Name": "Value 1",
 "Colors": {
   {"Basic colors": {
      "Primary colors": {
         [{"First Color":"Blue", "Second Color": "Red"}]
      }
    }
  }
}

使用JSON_EXTRACT(Name.Colors, '$.Basic_colors[0].Primary_colors)我可以返回一个结构体的数组,然后从结构体中提取值。但是,“Primary Color”中可以有多个项目,例如:

[{"First Color":"Blue", "Second Color": "Red"},{"First Color":"Green", "Second Color": "Orange"}]

理想的解决方案:

Name    |   First Color  |  Second Color  

Value 1 |   Blue         |  Red

Value 1 |   Green        |  Orange

我遇到的问题是,在使用 JSON_EXTRACT 时,“Primary Colors”无法识别为数组或结构。它被视为一个字符串(有道理,但也不能是 CAST() - 所以不能是 UNNEST()。

我遇到的第二个问题是,虽然我可以在使用 JSON_extract 时索引到数组中的 [0] 元素,但我无法为每个元素循环生成包含所有子元素的新数据行。

我不能使用 FNSPLIT,因为标准 SQL 不支持它。我相信我想 UNNEST(),但我不知道如何将 STRUCT 转换为被识别为数组中的第一个元素。我的蟒蛇饱和的大脑想要循环: 对于范围内的项目(len(json_array)):

我不能为此使用 Python(在生产环境中),一定有比在 SQL 宏中编写循环更简单的方法吗?

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    2020 年 5 月 1 日更新

    一个新函数 JSON_EXTRACT_ARRAY 刚刚添加到 JSON 列表中 功能。此函数允许您将 JSON 文档的内容提取为 一个字符串数组。

    所以在下面你可以用内置函数 JSON_EXTRACT_ARRAY 替换 json2array UDF 的使用,如下例所示

    #standardSQL
    SELECT 
      JSON_EXTRACT_SCALAR(json,'$.Name') Name, 
      JSON_EXTRACT_SCALAR(item, '$.First_Color') First_Color,
      JSON_EXTRACT_SCALAR(item, '$.Second_Color') Second_Color
    FROM `project.dataset.table`, 
    UNNEST(JSON_EXTRACT_ARRAY(json,'$.Colors.Basic_colors.Primary_colors')) item
    

    ==============

    以下 BigQuery 标准 SQL 示例

    #standardSQL
    CREATE TEMP FUNCTION JsonToArray(input STRING)
    RETURNS ARRAY<STRING>
    LANGUAGE js AS """
      return JSON.parse(input).map(x=>JSON.stringify(x));
    """; 
    WITH `project.dataset.table` AS (
      SELECT '''{
      "Name": "Value 1",
      "Colors": {
        "Basic_colors": {"Primary_colors": [
          {"First_Color":"Blue", "Second_Color": "Red"},
          {"First_Color":"Green", "Second_Color": "Orange"}
         ]
       }
      }}''' json
    )
    SELECT 
      JSON_EXTRACT_SCALAR(json,'$.Name') Name, 
      JSON_EXTRACT_SCALAR(item, '$.First_Color') First_Color,
      JSON_EXTRACT_SCALAR(item, '$.Second_Color') Second_Color
    FROM `project.dataset.table`, 
    UNNEST(JsonToArray(JSON_EXTRACT(json,'$.Colors.Basic_colors.Primary_colors'))) item
    

    有输出

    Row Name    First_Color Second_Color     
    1   Value 1 Blue        Red  
    2   Value 1 Green       Orange
    

    【讨论】:

    • 现在测试 - 你是天赐之物!
    • 经过测试并且工作正常!你太棒了,非常感谢你。节日快乐!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2014-05-04
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多