[英]In Snowflake, how do I parse an unnamed JSON array and access each key with key value rather than array slicing methods?
I have a JSON array in Snowflake, where I need to parse into a table, ie, convert all information into a row.我在雪花中有一个 JSON 数组,我需要在其中解析成一个表,即将所有信息转换成一行。 Assume my table includes two columns: id and json_tag column.
假设我的表包含两列:id 和 json_tag 列。
An example row is as below:示例行如下:
{ [
json_tag
[
{
"key": "app.name",
"value": "myapp1"
},
{
"key": "device.name",
"value": "myiPhone11"
},
{
"key": "iOS.dist",
"value": "latestDist5"
}
]
This is not a standard example, another example can have 5 or even 6 with new key names.这不是一个标准的例子,另一个例子可以有 5 个甚至 6 个新的键名。 An example is below:
下面是一个例子:
{ [
json_tag
[
{
"key": "app.name",
"value": "myapp2"
},
{
"key": "app.cost",
"value": "$2.99"
},
{
"key": "device.name",
"value": "myiPhoneX"
},
{
"key": "device.color",
"value": "gold"
},
{
"key": "iOS.dist",
"value": "latestDist4.9"
}
]
What I want is working on a table (without creating a new one) where the json row is split into columns as below:我想要的是处理一张表(不创建新表),其中 json 行被分成如下列:
id app.name app.cost device.name device.color iOS.dist
1 myapp1 null myiPhone11 null latestDist5
2 myapp2 $2.99 myiPhoneX gold latestDist4.9
I tried the following snippet:我尝试了以下代码段:
with parsed_tb as (
select id,
to_variant(parse_json(json_tag)) as parsed_json_tag
from mytable
)
select parsed_json_tag[0]:value::varchar as app_name,
parsed_json_tag[1]:value::varchar as app_cost,
parsed_json_tag[2]:value::varchar as device_name
from tb;
As you can imagine, the snippet above does not work when there is no app.cost in key values or every row differs in number of keys and values.可以想象,当键值中没有 app.cost 或每一行的键和值的数量不同时,上面的代码段不起作用。
I tried lateral flatten
command in Snowflake, but out creates many rows and I cannot figure out how to put them in columns in the same row.我在雪花中尝试了
lateral flatten
命令,但是创建了很多行,我无法弄清楚如何将它们放在同一行的列中。 I also tried using recursive
command, and could not achieve it.我也尝试使用
recursive
命令,但无法实现。
So my question is:所以我的问题是:
How can I access a key by its name rather than slicing an array as I do above?如何按名称访问键,而不是像上面那样对数组进行切片? - this would solve my problem I guess.
- 我想这会解决我的问题。
If #1 solution I imagine does not fix, how can I attain the table above?如果我想的 #1 解决方案不能解决,我怎样才能获得上表?
I have found a solution to this problem with the help of following thread:在以下线程的帮助下,我找到了解决此问题的方法:
Mysql, reshape data from long / tall to wide Mysql,从长/高到宽重塑数据
Solution is first parsing json column with unique identifier, and then lateral flattening and then grouping the results by unique identifier [formatting table from long to wide as given in the link above].解决方案是首先使用唯一标识符解析 json 列,然后横向展平,然后按唯一标识符对结果进行分组[格式表从长到宽,如上面的链接中给出的]。
So for the examples I provided above, the solution would be as follows:因此,对于我上面提供的示例,解决方案如下:
with tb as (
select id,
to_variant(parse_json(json_tags)) as parsed_json_tags
from mytable
),
flattened as (
select id,
VALUE:value::string as value,
VALUE:key::string as key
from mytable, lateral flatten(input => (tb.parsed_json_tags))
)
select id,
MAX( IFF( key='app.name', value, NULL ) ) AS app_name,
MAX( IFF( key='app.cost', value, NULL ) ) AS app_cost,
MAX( IFF( key='device.name', value, NULL ) ) AS device_name,
MAX( IFF( key='device.color', value, NULL ) ) AS device_color,
MAX( IFF( key='iOS.dist', value, NULL ) ) AS ios_dist
from flattened
group by 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.