从雪花中的子查询创建JSON

问题描述

我想从值列表创建JSON字符串,但是我以前从未使用过JSON。 请参阅下面的图像,这是我的2个表格以及我想在右侧创建的内容

enter image description here

我尝试了这个,但是它不起作用(对我的幼稚...但是我认为这将是它的逻辑实现)

select a.property_key,to_JSON( select application_ID from tableB where a.property_key = b.property_key) as application_list
  from tableA a

我将非常感谢您的帮助。 我尝试使用Google进行搜索,但发现雪花文档非常混乱。

解决方法

以下是如何将行转换为单个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_COMMENT
)) as MY_JSON
from "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1"."NATION";   

对于任一选项,请记住,JSON在Snowflake中被视为变体,并且大小限制为16mb。

,

使用窗口函数array_agg将一列简化为一个数组。

create table names (
  last_name varchar,first_name varchar
);

insert  into names 
    (last_name,first_name) 
values 
    ('waterman','tom'),('waterman','alex'),'david'),('barnett','rebecca'),'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","david" ]
barnett     ["rebecca","anne"  ]
barnett     ["rebecca","anne"  ]

然后可以使用last_name运算符将其减少为唯一的first_namedistinct对。

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;
,

您可以使用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;