从雪花中的子查询创建 JSON
Create JSON from a subquery in snowflake
我想从值列表创建一个 JSON 字符串,但我以前从未使用过 JSON。
请看下图我的 2 个表,以及我想在右边创建的内容。
我试过了,但它不起作用(请原谅我的天真......但我认为这将是它的逻辑实现)
select a.property_key
,to_JSON( select application_ID from tableB where a.property_key = b.property_key) as application_list
from tableA a
非常感谢您的帮助。
我尝试用谷歌搜索,但我发现雪花文档非常混乱。
下面是如何将行转换为单个 JSON 文档或一个 JSON 数组的示例:
-- Get some rows from a sample table
select * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.NATION;
-- Get each row as its own JSON using object_construct
select object_construct
(
'NATION', N_NATIONKEY,
'NAME', N_NAME,
'REGION_KEY', N_REGIONKEY,
'COMMENT', N_COMMENT
) as MY_JSON
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";
-- Get all rows as a JSON array by adding array_agg
select array_agg(object_construct
(
'NATION', N_NATIONKEY,
'NAME', N_NAME,
'REGION_KEY', N_REGIONKEY,
'COMMENT', N_COMMENT
)) as MY_JSON
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";
对于任一选项,请记住 JSON 在 Snowflake 中被视为变体并且有 16mb 的大小限制。
您可以使用 ARRAYAGG 函数将值转换为数组,然后使用 TO_JSON 函数将其进一步转换为 JSON。
select
b.property_key PROPERTY_KEY,
to_json(( arrayagg(b.APPLICATION_ID) within group (order by b.APPLICATION_ID) ) ) APPLICATION_IDS from table_b b, table_a a where b.property_key = a.property_key group by 1;
使用 window 函数 array_agg
将列缩减为数组。
create table names (
last_name varchar,
first_name varchar
);
insert into names
(last_name, first_name)
values
('waterman', 'tom'),
('waterman', 'alex'),
('waterman', 'david'),
('barnett', 'rebecca'),
('barnett', 'anne');
select
last_name,
array_agg(first_name) over (partition by last_name) first_names
from names;
上面的查询产生以下结果:
LAST_NAME FIRST_NAMES
waterman ["tom", "alex", "david" ]
waterman ["tom", "alex", "david" ]
waterman ["tom", "alex", "david" ]
barnett ["rebecca", "anne" ]
barnett ["rebecca", "anne" ]
然后您可以使用 distinct
运算符将其简化为唯一的 last_name
、first_name
对。
select
distinct
last_name,
array_agg(first_name) over (partition by last_name) first_names
from names;
要将 array_agg
返回的值数组转换为 JSON,您可以简单地使用 ::variant
.
转换结果
select
distinct
last_name,
array_agg(first_name) over (partition by last_name)::variant first_names
from names;
我想从值列表创建一个 JSON 字符串,但我以前从未使用过 JSON。 请看下图我的 2 个表,以及我想在右边创建的内容。
我试过了,但它不起作用(请原谅我的天真......但我认为这将是它的逻辑实现)
select a.property_key
,to_JSON( select application_ID from tableB where a.property_key = b.property_key) as application_list
from tableA a
非常感谢您的帮助。 我尝试用谷歌搜索,但我发现雪花文档非常混乱。
下面是如何将行转换为单个 JSON 文档或一个 JSON 数组的示例:
-- Get some rows from a sample table
select * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.NATION;
-- Get each row as its own JSON using object_construct
select object_construct
(
'NATION', N_NATIONKEY,
'NAME', N_NAME,
'REGION_KEY', N_REGIONKEY,
'COMMENT', N_COMMENT
) as MY_JSON
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";
-- Get all rows as a JSON array by adding array_agg
select array_agg(object_construct
(
'NATION', N_NATIONKEY,
'NAME', N_NAME,
'REGION_KEY', N_REGIONKEY,
'COMMENT', N_COMMENT
)) as MY_JSON
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";
对于任一选项,请记住 JSON 在 Snowflake 中被视为变体并且有 16mb 的大小限制。
您可以使用 ARRAYAGG 函数将值转换为数组,然后使用 TO_JSON 函数将其进一步转换为 JSON。
select
b.property_key PROPERTY_KEY,
to_json(( arrayagg(b.APPLICATION_ID) within group (order by b.APPLICATION_ID) ) ) APPLICATION_IDS from table_b b, table_a a where b.property_key = a.property_key group by 1;
使用 window 函数 array_agg
将列缩减为数组。
create table names (
last_name varchar,
first_name varchar
);
insert into names
(last_name, first_name)
values
('waterman', 'tom'),
('waterman', 'alex'),
('waterman', 'david'),
('barnett', 'rebecca'),
('barnett', 'anne');
select
last_name,
array_agg(first_name) over (partition by last_name) first_names
from names;
上面的查询产生以下结果:
LAST_NAME FIRST_NAMES
waterman ["tom", "alex", "david" ]
waterman ["tom", "alex", "david" ]
waterman ["tom", "alex", "david" ]
barnett ["rebecca", "anne" ]
barnett ["rebecca", "anne" ]
然后您可以使用 distinct
运算符将其简化为唯一的 last_name
、first_name
对。
select
distinct
last_name,
array_agg(first_name) over (partition by last_name) first_names
from names;
要将 array_agg
返回的值数组转换为 JSON,您可以简单地使用 ::variant
.
select
distinct
last_name,
array_agg(first_name) over (partition by last_name)::variant first_names
from names;