扁平化雪花中的嵌套JSON

时间:2020-09-16 13:02:35

标签: snowflake-cloud-data-platform

这是JSON的示例(类型可以更多,也可以更少)。 我想结束(顺序不重要):

国家/地区IC 国家,ES 国家,东南 国家,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: 显然不能过去更多代码...需要更多详细信息。

4 个答案:

答案 0 :(得分:0)

您在使用https://docs.snowflake.com/en/sql-reference/functions/flatten.html中记录的FLATTEN()吗?

我们需要做更多的工作,但是您最终可能会遇到类似这样的情况:

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

答案 1 :(得分:0)

前一段时间,我实际上为此写了一段文档:

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

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

答案 2 :(得分:0)

如果我们假设有一个定义(并填充)的表,如下所示:

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
;

答案 3 :(得分:0)

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