在雪花中展平嵌套的 JSON

Posted

技术标签:

【中文标题】在雪花中展平嵌套的 JSON【英文标题】:Flatten nested JSON in snowflake 【发布时间】:2020-09-16 13:02:35 【问题描述】:

这是 JSON 的一个示例(它可以是更多或更少的类型和/或值。 我想结束(顺序不重要):

国家,IC 国家,ES 国家,SE 国家,GB 国家,美国 分类、电影聊天

JSON


  "list": [
    
      "element": 
        "comparison": "anyOf",
        "logical": "and",
        "type": "Countries",
        "value": 
          "list": [
            
              "element": "IC"
            ,
            
              "element": "ES"
            ,
            
              "element": "SE"
            ,
            
              "element": "GB"
            ,
            
              "element": "US"
            
          ]
        
      
    ,
    
      "element": 
        "comparison": "anyOf",
        "logical": "and",
        "type": "Categories",
        "value": 
          "list": [
            
              "element": "film-chat"
            
          ]
        
      
    
  ]

到目前为止我已经尝试过,可能是第 17 次迭代: 显然无法通过更多代码...需要更多详细信息。

【问题讨论】:

【参考方案1】:

不久前,我实际上围绕它写了一篇文档:

https://community.snowflake.com/s/article/Dynamically-extract-multi-level-JSON-object-using-lateral-flatten

它允许动态提取所有嵌套级别最高为第 4 级的字段(您可以随时添加更多),然后您可以使用常规选择按您需要的方式对它们进行排序。

【讨论】:

是的,目前正在这样做,但我没有得到第 5 级值的密钥。【参考方案2】:

您是否使用FLATTEN() 记录在https://docs.snowflake.com/en/sql-reference/functions/flatten.html

我们需要做更多的工作,但您最终可能会得到以下结果:

with tbl as (select parse_json($1) json from values ('"list":["element":"comparison":"anyOf","logical":"and","type":"Countries","value":"list":["element":"IC","element":"ES","element":"SE","element":"GB","element":"US"],"element":"comparison":"anyOf","logical":"and","type":"Categories","value":"list":["element":"film-chat"]]'))
select *
from tbl,
  lateral flatten(json:list) list_l1 ,
  lateral flatten(list_l1.value:element) element_l1,
  lateral flatten(element_l1.value:list, OUTER => TRUE) list_l2 ,
  lateral flatten(list_l2.value:element, OUTER => TRUE) element_l2

【讨论】:

看到了,但没能成功。会再试一次。【参考方案3】:

如果我们假设我们有一个如下定义(和填充)的表:

CREATE OR REPLACE TEMPORARY TABLE MY_TABLE (
  MY_DICT  VARIANT
)
AS
  SELECT PARSE_JSON($1) AS MY_DICT
    FROM VALUES ($$
  
    "list": [
      
        "element": 
          "comparison": "anyOf",
          "logical": "and",
          "type": "Countries",
          "value": 
            "list": [
              
                "element": "IC"
              ,
              
                "element": "ES"
              ,
              
                "element": "SE"
              ,
              
                "element": "GB"
              ,
              
                "element": "US"
              
            ]
          
        
      ,
      
        "element": 
          "comparison": "anyOf",
          "logical": "and",
          "type": "Categories",
          "value": 
            "list": [
              
                "element": "film-chat"
              
            ]
          
        
      
    ]
  
  $$)
;

那么我们可以使用这个查询来返回你指定的信息:

SELECT LISTAGG(F1.VALUE:"element":"type"::VARCHAR || ', ' || F2.VALUE:"element"::VARCHAR, ' ')
  FROM MY_TABLE
      ,LATERAL FLATTEN(MY_TABLE.MY_DICT:"list") F1
      ,LATERAL FLATTEN(F1.VALUE:"element":"value":"list") F2
;

编辑(基于您关于想要行的评论,而不是连接的字符串列):

只需去掉LISTAGG(),如下:

SELECT F1.VALUE:"element":"type"::VARCHAR || ', ' || F2.VALUE:"element"::VARCHAR AS TYPE_ELEMENT
  FROM MY_TABLE
      ,LATERAL FLATTEN(MY_TABLE.MY_DICT:"list") F1
      ,LATERAL FLATTEN(F1.VALUE:"element":"value":"list") F2
;

如果你想要一个简单的结果集,有 2 列(你的规范中不清楚),那么你可以使用这个:

SELECT F1.VALUE:"element":"type"::VARCHAR AS TYPE
      ,F2.VALUE:"element"::VARCHAR AS ELEMENT
  FROM MY_TABLE
      ,LATERAL FLATTEN(MY_TABLE.MY_DICT:"list") F1
      ,LATERAL FLATTEN(F1.VALUE:"element":"value":"list") F2
;

【讨论】:

这行得通。现在它在一列中。需要将该列变为行... 但是当无限制时我得到“String '(LISTAGG result)' is too long and will be truncated”【参考方案4】:
select
    id,
    f1.value:element:type::string type,
    f2.value:element::string element
from
    table,
    lateral flatten(input => table.json, path => 'list') f1,
    lateral flatten(input => f1.value:element:value:list) f2

【讨论】:

以上是关于在雪花中展平嵌套的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫数据框中展平嵌套的 Json

带有 ORDER BY 的雪花 JSON 扁平化

使用 jq 展平嵌套的 JSON

有没有办法在火花流中展平嵌套的 JSON?

用嵌套列表和嵌套字典列表展平一个非常大的 Json

如何在 Azure 流分析中展平嵌套的 json 数据