我在雪花中有以下内容:
create or replace table json_tmp as select column1 as id, parse_json(column2) as c
from VALUES (1,
'{"id": "0x1",
"custom_vars": [
{ "key": "a", "value": "foo" },
{ "key": "b", "value": "bar" }
] }') v;
基于as the descriptor how-to states,我希望将它们变成一个如下表:
+-------+---------+-----+-----+
| db_id | json_id | a | b |
+-------+---------+-----+-----+
+-------+---------+-----+-----+
| 1 | 0x1 | foo | bar |
+-------+---------+-----+-----+
这是我试过的查询;它导致SQL编译错误:“对象'CUSTOM_VARS'不存在。”
select json_tmp.id as dbid,
f.value:id as json_id,
a.v,
b.v
from json_tmp,
lateral flatten(input => json_tmp.c) as f,
lateral flatten(input => f.value:custom_vars) as custom_vars,
lateral (select value:value as v from custom_vars where value:key = 'a') as a,
lateral (select value:value as v from custom_vars where value:key = 'b') as b;
这里的错误究竟是什么?有没有更好的方法来进行这种转变?
答案 0 :(得分:1)
注意 - 您的解决方案实际上并未执行任何联接 - flatten是" streaming"操作,它"爆炸"输入,然后选择它想要的行。如果数据中只有2个属性,则应该相当快。但是,如果没有,则可能导致不必要的数据爆炸(例如,如果您有1000个属性)。
最快的解决方案取决于您的数据结构的准确程度,以及您可以对输入采取的假设。例如,如果你知道' a'和' b'总是按照这个顺序,你显然可以使用
select
id as db_id,
c:id,
c:custom_vars[0].value,
c:custom_vars[1].value
from json_tmp;
如果您知道custom_vars
总是2个元素,但订单未知,您可以这样做。
select
id as db_id,
c:id,
iff(c:custom_vars[0].key = 'a', c:custom_vars[0].value, c:custom_vars[1].value),
iff(c:custom_vars[0].key = 'b', c:custom_vars[0].value, c:custom_vars[1].value)
from json_tmp;
如果custom_vars的大小未知,您可以创建一个类似extract_key(custom_vars, key)
的JavaScript函数,该函数将迭代custom_vars
并返回找到的value
key
(或者null
或<empty_string>
,如果没有找到)。
希望这会有所帮助。如果没有,请提供有关您的问题的更多详细信息(数据等)。
答案 1 :(得分:0)
以下查询似乎有效:
select json_tmp.id as dbid,
json_tmp.c:id as json_id,
a.value:value a,
b.value:value b
from
json_tmp,
lateral flatten(input => json_tmp.c, path => 'custom_vars') a,
lateral flatten(input => json_tmp.c, path => 'custom_vars') b
where a.value:key = 'a' and b.value:key = 'b'
;
我宁愿过滤子查询而不是加入,所以我仍然有兴趣看到其他答案。