繁体   English   中英

在雪花中解析 JSON

[英]Parsing JSON in Snowflake

我正在尝试使用 Snowflake 中的后侧 function 解析 Snowflake 中的以下嵌套 JSON 但我希望“GoalTime”中的每个嵌套列显示为一列。 例如,

GoalTime_InDoorOpen         
2020-03-26T12:58:00-04:00   

GoalTime_InLastOff
null

GoalTime_OutStartBoarding
2020-03-27T14:00:00-04:00  
"GoalTime": [
    {
      "GoalName": "GoalTime_InDoorOpen",
      "GoalTime": "2020-03-26T12:58:00-04:00"
    },
    {
      "GoalName": "GoalTime_InLastOff"
    },
    {
      "GoalName": "GoalTime_InReadyToTow"
    },
    {
      "GoalName": "GoalTime_OutTowAtGate"
    },
    {
      "GoalName": "GoalTime_OutStartBoarding",
      "GoalTime": "2020-03-27T14:00:00-04:00"
    },

或者如果您有很多行(似乎是航班),因此您需要为每个航班列此代码就是您所追求的

with data as (
select flight_code, parse_json(json) as json from values ('nz101','{GoalTime:[{"GoalName": "GoalA", "GoalTime": "2020-03-26T12:58:00-04:00"}, {"GoalName": "GoalB"}]}'),
                                                 ('nz201','{GoalTime:[{"GoalName": "GoalA"}, {"GoalName": "GoalB", "GoalTime": "2020-03-26T12:58:00-02:00"}]}') 
                                                 j(flight_code, json)
), unrolled as (
select d.flight_code, f.value:GoalName as goal_name, f.value:GoalTime as goal_time
from data d,
lateral flatten (input => json:GoalTime) f
)
select * 
from unrolled
    pivot(min(goal_time) for goal_name in ('GoalA', 'GoalB'))
order by flight_code;

它给出了结果:

FLIGHT_CODE 'GoalA'                       'GoalB'
nz101       "2020-03-26T12:58:00-04:00"   null
nz201       null                          "2020-03-26T12:58:00-02:00"
create or replace function JSON_STRING()
returns string
language javascript
as
$$
return `
[
  {
        "GoalName": "GoalTime_InDoorOpen",
        "GoalTime": "2020-03-26T12:58:00-04:00"
    },
    {
        "GoalName": "GoalTime_InLastOff"
    },
    {
        "GoalName": "GoalTime_InReadyToTow"
    },
    {
        "GoalName": "GoalTime_OutTowAtGate"
    },
    {
        "GoalName": "GoalTime_OutStartBoarding",
        "GoalTime": "2020-03-27T14:00:00-04:00"
    }
]
`;
$$;

select value:GoalName::string as GoalName, value:GoalTime::timestamp as GoalTime
from lateral flatten(input => parse_json(JSON_STRING()));

-- See how the lateral flatten combination works on a JSON variant:
select * from lateral flatten(input => parse_json(JSON_STRING()));

我写这个是为了在任何雪花工作表中运行,不需要表格。 顶部的 function 仅允许将 JSON 作为多行字符串写入其下方的 SQL 语句中。 它除了代表一个包含您的 JSON 的字符串之外没有其他用途。

第 1 步是 PARSE_JSON,它将字符串转换为格式为 JSON object 的变体数据类型。

第 2 步是横向压平。 如果您对此进行 select 星号,它将返回许多列。 其中之一是“价值”。

第 3 步是提取您想要的属性,使用 single: 表示属性名称和点以从那里向下遍历节点(如果有的话)。

第 4 步是使用 double:: 表示法将属性转换为您想要的数据类型。 如果您要对列进行比较,尤其是在连接键中进行比较,这一点尤其重要。

请注意,JSON 有一个轻微的无效部分不允许它解析。 在顶层,数组有一个没有解析的属性。 我删除了它以允许解析。

可能接近您所寻求的是使用标准 SQL UNION 语句。

鉴于以下是正确的重新创建解决方案:

  • 创建了一个表“JSON_GOALS”,其中一列用于原始 JSON,称为 GOALS_RAW
  • You have loaded JSON data into a table as the raw JSON, with compliant JSON object array syntax, and a parent, GoalTimeGroup, ex: {[{}]}, so
{
    "GoalTimeGroup": [{
            "GoalName": "GoalTime_InDoorOpen",
            "GoalTime": "2020-03-26T12:58:00-04:00"
        },
        {
            "GoalName": "GoalTime_InLastOff"
        },
        {
            "GoalName": "GoalTime_InReadyToTow"
        },
        {
            "GoalName": "GoalTime_OutTowAtGate"
        },
        {
            "GoalName": "GoalTime_OutStartBoarding",
            "GoalTime": "2020-03-27T14:00:00-04:00"
        }
    ]
}

这样做允许您使用以下语法在 Snowflake 中编写相当标准的 JSON 检索:

SELECT GOALS_RAW:GoalTimeGroup[0].GoalName, GOALS_RAW:GoalTimeGroup[1].GoalName, GOALS_RAW:GoalTimeGroup[2].GoalName
FROM JSON_GOALS 
UNION
SELECT GOALS_RAW:GoalTimeGroup[0].GoalTime, GOALS_RAW:GoalTimeGroup[1].GoalTime, GOALS_RAW:GoalTimeGroup[2].GoalName
FROM JSON_GOALS 
;

这使您更接近您正在寻找的答案,并且似乎提供了一个更简单的解决方案。 您还可以根据每个目标 object 的 JSON object 属性来控制所需的行数。

增强这一点的建议是创建一个 function 可以检测每个嵌套元素的深度,并可能自动生成“n”个列的索引。

下面的库提供了一个名为“ExecuteAll”的方法,其中一个参数是“tags”,因此如果您提供一组标签和值,所有这些都将被解析和验证,并保留来自 Snowflake 的 sql 注入保护的功能.

雪花-multisql

暂无
暂无

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

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