在雪花上创建一个新的嵌套JSON专栏

发布于 2025-02-11 15:29:48 字数 1101 浏览 0 评论 0原文

我正在尝试将雪花表中的几列转换为嵌套的JSON,并尝试了Object_Construct& 但是,无法创建嵌套的JSON

输入

IDproduct_1Product_1Products_2PRODUCT_2_PCHERASE_DATE
100XCTMR01/02/2003-array_construct
product_1_purchase_date: 2016XCTMR09/09/2021

输出:

IDJSON_COMBIND
100[{“ PRODECT_1”:{“ NAME”:“ XCTMR”,“ PRODECT_1_PURCHASE_DATE”:“ 01/02/2003”}},{01/02/2003“}},{ product_2“:{“ name”:“ iopwer”,“ product_2_purchase_date”:“ 01/02/2005”}}}]
200[{“ produck_1”:{“ name”:“ aqwyu”:“ aqwyu”,product_1_purchase_date“:” 11/20 /2016“}},{“ product_2”:{“ name”:“ xctmr”,“ product_2_purchase_date”:“ 09/09/2021”}}]]

I'm trying to convert a few columns in Snowflake table into a nested JSON and have tried OBJECT_CONSTRUCT & ARRAY_CONSTRUCT - but, unable to create a nested JSON

Input:

idproduct_1product_1_purchase_dateproduct_2product_2_purchase_date
100XCTMR01/02/2003IOPWER01/02/2005
200AQWYU11/20/2016XCTMR09/09/2021

Output:

idjson_combined
100[ { "product_1": { "name": "XCTMR", "product_1_purchase_date": "01/02/2003" } }, { "product_2": { "name": "IOPWER", "product_2_purchase_date": "01/02/2005" } } ]
200[ { "product_1": { "name": "AQWYU", "product_1_purchase_date": "11/20/2016" } }, { "product_2": { "name": "XCTMR", "product_2_purchase_date": "09/09/2021" } } ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

作妖 2025-02-18 15:29:48

解决方案,仅使用硬编码字段名称,只需要放置功能array_constructobject_construct以正确的顺序。

with cte(id,product_1,product_1_purchase_date,product_2,product_2_purchase_date) as
(select * from values
(100,'XCTMR','01/02/2003','IOPWER','01/02/2005'),
(200,'AQWYU','11/20/2016','XCTMR','09/09/2021')
)select
  id,
  array_construct(object_construct('product_1',
  object_construct('name',product_1,'product_1_purchase_date',
  product_1_purchase_date)),
  object_construct('product_2',
  object_construct('name',product_2,'product_2_purchase_date',
  product_2_purchase_date)) ) as JSON_COMBINED
from cte;
+-----+-----------------------------------------------+
|  ID | JSON_COMBINED                                 |
|-----+-----------------------------------------------|
| 100 | [                                             |
|     |   {                                           |
|     |     "product_1": {                            |
|     |       "name": "XCTMR",                        |
|     |       "product_1_purchase_date": "01/02/2003" |
|     |     }                                         |
|     |   },                                          |
|     |   {                                           |
|     |     "product_2": {                            |
|     |       "name": "IOPWER",                       |
|     |       "product_2_purchase_date": "01/02/2005" |
|     |     }                                         |
|     |   }                                           |
|     | ]                                             |
| 200 | [                                             |
|     |   {                                           |
|     |     "product_1": {                            |
|     |       "name": "AQWYU",                        |
|     |       "product_1_purchase_date": "11/20/2016" |
|     |     }                                         |
|     |   },                                          |
|     |   {                                           |
|     |     "product_2": {                            |
|     |       "name": "XCTMR",                        |
|     |       "product_2_purchase_date": "09/09/2021" |
|     |     }                                         |
|     |   }                                           |
|     | ]                                             |
+-----+-----------------------------------------------+

以下是具有更多动力的 -

  • CTE是纯数据。
  • CTE_1正在创建两个伪柱,一个用于字段名称product_x和
    object_agg我们
    无法在另一个聚合功能中使用汇总函数,因此
    我们需要多次进行聚合(在这里两次)。在此CTE中将划分更改为2列的数量。我们还可以在此处添加一个子问题来进行此计算,但是出于该解决方案的目的,我将其保留为硬编码。
    CTE_1还在执行undivot产品相关的列的主要作业中,以进行动态分组。
  • CTE_2是聚合编号-1,其输出如下(显示截短的输出)。最终查询执行主array_agg
+-----+-----------+----------------------------------------------+
|  ID | RN        | JSON_COMBINED_1                              |
|-----+-----------+----------------------------------------------|
| 100 | product_1 | {                                            |
|     |           |   "product_1": {                             |
|     |           |     "PRODUCT_1_PURCHASE_DATE": "01/02/2003", |
|     |           |     "name": "XCTMR"                          |
|     |           |   }                                          |
|     |           | }                                            |
| 200 | product_2 | {                                            |
|     |           |   "product_2": {                             |
|     |           |     "PRODUCT_2_PURCHASE_DATE": "09/09/2021", |
|     |           |     "name": "XCTMR"                          |
|     |           |   }                                          |
|     |           | }                                            |
+-----+-----------+----------------------------------------------+

主要查询 -

with cte(id,product_1,product_1_purchase_date,product_2,product_2_purchase_date) as
 (select * from values
 (100,'XCTMR','01/02/2003','IOPWER','01/02/2005'),
 (200,'AQWYU','11/20/2016','XCTMR','09/09/2021')
),cte_1 as (
 select id,
 case when regexp_like(product_field,'product_[[:digit:]]+','i') 
 then 'name' else product_field end p_field,
 product_val,
 concat('product_',
 to_char(ceil(row_number() over (partition by id order by null)/2)))   rn
from cte
unpivot (product_val for product_field in  (product_1,product_1_purchase_date,
 product_2,product_2_purchase_date))
), cte_2 as (
 select id,rn,
 object_construct(rn,object_agg(p_field,to_variant(product_val)))  JSON_COMBINED_1
 from cte_1
 group by id,rn
) select id, array_agg(JSON_COMBINED_1) JSON_COMBINED
 from cte_2
 group by id
 order by id;

最终输出从上方查询(具有动态) -

+-----+------------------------------------------------+
|  ID | JSON_COMBINED                                  |
|-----+------------------------------------------------|
| 100 | [                                              |
|     |   {                                            |
|     |     "product_1": {                             |
|     |       "PRODUCT_1_PURCHASE_DATE": "01/02/2003", |
|     |       "name": "XCTMR"                          |
|     |     }                                          |
|     |   },                                           |
|     |   {                                            |
|     |     "product_2": {                             |
|     |       "PRODUCT_2_PURCHASE_DATE": "01/02/2005", |
|     |       "name": "IOPWER"                         |
|     |     }                                          |
|     |   }                                            |
|     | ]                                              |
| 200 | [                                              |
|     |   {                                            |
|     |     "product_2": {                             |
|     |       "PRODUCT_2_PURCHASE_DATE": "09/09/2021", |
|     |       "name": "XCTMR"                          |
|     |     }                                          |
|     |   },                                           |
|     |   {                                            |
|     |     "product_1": {                             |
|     |       "PRODUCT_1_PURCHASE_DATE": "11/20/2016", |
|     |       "name": "AQWYU"                          |
|     |     }                                          |
|     |   }                                            |
|     | ]                                              |
+-----+------------------------------------------------+
2 Row(s) produced.

Solution, with hard-coding field-names only, just need to put functions ARRAY_CONSTRUCT and OBJECT_CONSTRUCT in proper order.

with cte(id,product_1,product_1_purchase_date,product_2,product_2_purchase_date) as
(select * from values
(100,'XCTMR','01/02/2003','IOPWER','01/02/2005'),
(200,'AQWYU','11/20/2016','XCTMR','09/09/2021')
)select
  id,
  array_construct(object_construct('product_1',
  object_construct('name',product_1,'product_1_purchase_date',
  product_1_purchase_date)),
  object_construct('product_2',
  object_construct('name',product_2,'product_2_purchase_date',
  product_2_purchase_date)) ) as JSON_COMBINED
from cte;
+-----+-----------------------------------------------+
|  ID | JSON_COMBINED                                 |
|-----+-----------------------------------------------|
| 100 | [                                             |
|     |   {                                           |
|     |     "product_1": {                            |
|     |       "name": "XCTMR",                        |
|     |       "product_1_purchase_date": "01/02/2003" |
|     |     }                                         |
|     |   },                                          |
|     |   {                                           |
|     |     "product_2": {                            |
|     |       "name": "IOPWER",                       |
|     |       "product_2_purchase_date": "01/02/2005" |
|     |     }                                         |
|     |   }                                           |
|     | ]                                             |
| 200 | [                                             |
|     |   {                                           |
|     |     "product_1": {                            |
|     |       "name": "AQWYU",                        |
|     |       "product_1_purchase_date": "11/20/2016" |
|     |     }                                         |
|     |   },                                          |
|     |   {                                           |
|     |     "product_2": {                            |
|     |       "name": "XCTMR",                        |
|     |       "product_2_purchase_date": "09/09/2021" |
|     |     }                                         |
|     |   }                                           |
|     | ]                                             |
+-----+-----------------------------------------------+

Below is with more dynamism -

  • CTE is pure data.
  • CTE_1 is creating two pseudo-columns, one for field name product_x and
    another to be used as grouping criteria later in OBJECT_AGG We
    cannot use aggregate function inside another aggregate function, so
    we need to do aggregation multiple times (twice here). Change divide by 2 in this CTE to the number of product_x columns. We can also add a sub-query here to do this calculation, but for the purpose of this solution I've left it as hard-coded.
    CTE_1 is also doing the main job of UNPIVOT product related column into rows for dynamic grouping.
  • CTE_2 is aggregation number - 1, with output like below (showing truncated output). Final query does the main ARRAY_AGG.
+-----+-----------+----------------------------------------------+
|  ID | RN        | JSON_COMBINED_1                              |
|-----+-----------+----------------------------------------------|
| 100 | product_1 | {                                            |
|     |           |   "product_1": {                             |
|     |           |     "PRODUCT_1_PURCHASE_DATE": "01/02/2003", |
|     |           |     "name": "XCTMR"                          |
|     |           |   }                                          |
|     |           | }                                            |
| 200 | product_2 | {                                            |
|     |           |   "product_2": {                             |
|     |           |     "PRODUCT_2_PURCHASE_DATE": "09/09/2021", |
|     |           |     "name": "XCTMR"                          |
|     |           |   }                                          |
|     |           | }                                            |
+-----+-----------+----------------------------------------------+

Main query -

with cte(id,product_1,product_1_purchase_date,product_2,product_2_purchase_date) as
 (select * from values
 (100,'XCTMR','01/02/2003','IOPWER','01/02/2005'),
 (200,'AQWYU','11/20/2016','XCTMR','09/09/2021')
),cte_1 as (
 select id,
 case when regexp_like(product_field,'product_[[:digit:]]+','i') 
 then 'name' else product_field end p_field,
 product_val,
 concat('product_',
 to_char(ceil(row_number() over (partition by id order by null)/2)))   rn
from cte
unpivot (product_val for product_field in  (product_1,product_1_purchase_date,
 product_2,product_2_purchase_date))
), cte_2 as (
 select id,rn,
 object_construct(rn,object_agg(p_field,to_variant(product_val)))  JSON_COMBINED_1
 from cte_1
 group by id,rn
) select id, array_agg(JSON_COMBINED_1) JSON_COMBINED
 from cte_2
 group by id
 order by id;

Final output from above query (with dynamism) -

+-----+------------------------------------------------+
|  ID | JSON_COMBINED                                  |
|-----+------------------------------------------------|
| 100 | [                                              |
|     |   {                                            |
|     |     "product_1": {                             |
|     |       "PRODUCT_1_PURCHASE_DATE": "01/02/2003", |
|     |       "name": "XCTMR"                          |
|     |     }                                          |
|     |   },                                           |
|     |   {                                            |
|     |     "product_2": {                             |
|     |       "PRODUCT_2_PURCHASE_DATE": "01/02/2005", |
|     |       "name": "IOPWER"                         |
|     |     }                                          |
|     |   }                                            |
|     | ]                                              |
| 200 | [                                              |
|     |   {                                            |
|     |     "product_2": {                             |
|     |       "PRODUCT_2_PURCHASE_DATE": "09/09/2021", |
|     |       "name": "XCTMR"                          |
|     |     }                                          |
|     |   },                                           |
|     |   {                                            |
|     |     "product_1": {                             |
|     |       "PRODUCT_1_PURCHASE_DATE": "11/20/2016", |
|     |       "name": "AQWYU"                          |
|     |     }                                          |
|     |   }                                            |
|     | ]                                              |
+-----+------------------------------------------------+
2 Row(s) produced.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文