Sql 在Snowflake中解析JSON

Sql 在Snowflake中解析JSON,sql,json,azure,snowflake-cloud-data-platform,Sql,Json,Azure,Snowflake Cloud Data Platform,我试图使用Snowflake中的Lateral函数解析Snowflake中下面嵌套的JSON,但我希望“GoalTime”中的每个嵌套列都显示为一个列。比如说, GoalTime_InDoorOpen 2020-03-26T12:58:00-04:00 GoalTime_InLastOff null GoalTime_OutStartBoarding 2020-03-27T14:00:00-04:00 我写这篇文章是为了在任何雪花工作表中运行,不需要表格。上面的

我试图使用Snowflake中的Lateral函数解析Snowflake中下面嵌套的JSON,但我希望“GoalTime”中的每个嵌套列都显示为一个列。比如说,

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

GoalTime_InLastOff
null

GoalTime_OutStartBoarding
2020-03-27T14:00:00-04:00  
我写这篇文章是为了在任何雪花工作表中运行,不需要表格。上面的函数只允许JSON作为多行字符串写入下面的SQL语句中。它除了表示包含JSON的字符串之外没有其他用途

第1步是解析_JSON,它将字符串转换为格式为JSON对象的变量数据类型

第二步是横向展平。如果在上面选择星号,它将返回许多列。其中之一是“价值”

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

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

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

我写这篇文章是为了在任何雪花工作表中运行,不需要表格。上面的函数只允许JSON作为多行字符串写入下面的SQL语句中。它除了表示包含JSON的字符串之外没有其他用途

第1步是解析_JSON,它将字符串转换为格式为JSON对象的变量数据类型

第二步是横向展平。如果在上面选择星号,它将返回许多列。其中之一是“价值”

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

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

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

或者,如果您有许多行(看起来是航班),因此您需要为每个航班添加列,则此代码就是您要查找的代码

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"
或者,如果您有许多行(看起来是航班),因此需要为每个航班设置列,则此代码就是您要查找的代码

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"

可能最接近您所寻求的是使用标准的SQLUNION语句

如果要重新创建解决方案,请满足以下条件:

  • 创建了一个表“JSON\u GOALS”,其中有一列用于原始JSON,名为GOALS\u raw
  • 您已经将JSON数据作为原始JSON加载到一个表中,该表具有兼容的JSON对象数组语法和父级GoalTimeGroup,ex:{[{}]},因此
这样做可以使用以下语法在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 
;
这使您更接近您正在寻找的答案,并且似乎提供了一个更简单的解决方案。您还可以根据每个目标对象的JSON对象属性控制需要多少行


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

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

如果要重新创建解决方案,请满足以下条件:

  • 创建了一个表“JSON\u GOALS”,其中有一列用于原始JSON,名为GOALS\u raw
  • 您已经将JSON数据作为原始JSON加载到一个表中,该表具有兼容的JSON对象数组语法和父级GoalTimeGroup,ex:{[{}]},因此
这样做可以使用以下语法在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 
;
这使您更接近您正在寻找的答案,并且似乎提供了一个更简单的解决方案。您还可以根据每个目标对象的JSON对象属性控制需要多少行


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

下面的库提供了一个名为“ExecuteAll”的方法,其中一个参数是“tags”,因此如果您提供了一个标记和值数组,所有这些都将被解析和验证,并保持sql注入保护的特性不受雪花的影响


下面的库提供了一个名为“ExecuteAll”的方法,其中一个参数是“标记”,因此,如果您提供了一个标记和值数组,所有这些标记和值都将被解析和验证,并保持sql注入保护的功能不受雪花影响