试图从 Json 对象中排除特定列的并发症为什么要在 snowflake 上编写 SQL 查询
Complications trying to exclude a specific column from a Json object why writing an SQL query on snowflake
我是 Snowflake 的新手,我正在尝试编写一个 SQL 查询来创建一个 JSON 对象,同时从输出中排除特定列
table: 莱克斯
id
Amount
status
001
200
accept
001
100
accept
002
200
accept
002
100
accept
003
200
accept
到目前为止我的代码
With wt as (
Select *
FROM lex
),
-------Convert to JSON------
wt_json as (
select id,
ARRAY_AGG(object_construct_keep_null(*)) withdrawals
from wt
Group by id
)
select * from wt_json
这会产生类似于此的输出
id
withdrawals
01
[{id: 01, amount :200, status: accept},{id: 01, amount :100,status: accept}]
02
[{id: 02, amount :200, status: accept},{id: 02, amount :100,status: accept}]
03
[{id: 03, amount :200, status: accept}]
但是,我试图排除 JSON 对象中的 ID。
我想要达到的目标
id
withdrawals
01
[{ amount :200, status: accept},{ amount :100,status: accept}]
02
[{ amount :200, status: accept},{ amount :100,status: accept}]
03
[{ amount :200, status: accept}]
Returns an object containing the contents of the input (i.e.source) object with one or more keys removed.
With wt as (
Select *
FROM lex
),
-------Convert to JSON------
wt_json as (
select id,
ARRAY_AGG(OBJECT_DELETE(object_construct_keep_null(*), 'id')) withdrawals
from wt
Group by id
)
select * from wt_json
您正在 object_construct_keep_null
函数中使用 *。这意味着该对象是从所有可用列构造的。如果您不想要这个,那么请以 'key', value
的形式指定您想要的每一列。您可以单独包含“id”列来实现您想要的:
WITH src AS (
SELECT '01' AS "id", 200 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '01' AS "id", 100 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '02' AS "id", 200 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '02' AS "id", 100 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '03' AS "id", 200 AS "amount", 'accept' AS "status"
)
SELECT
"id"
, array_agg(
object_construct_keep_null(
'amount', "amount",
'status', "status"
)
) AS "withdrawals"
FROM src
GROUP BY "id"
结果:
id withdrawals
---------------------------------------------------------------------------------------------------
01 [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" }]
02 [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" }]
03 [ { "amount": 200, "status": "accept" }]
所以 OBJECT_DELETE 的问题是 id 必须与密钥大小写相同,因为 JSON 区分大小写,而 SQL 不区分大小写,因此默认情况下,它全部变为大写,因此在我下面的代码中,我允许 id
为 non-qouted,对于 OBJECT_DELETE 命令,它实际上是 'ID'
。
因此:
WITH wt AS (
SELECT * FROM VALUES
('001', 200, 'accept'),
('001', 100, 'accept'),
('002', 200, 'accept'),
('002', 100, 'accept'),
('003', 200, 'accept')
v(id, amount, status)
)
SELECT w.id,
ARRAY_AGG(object_construct_keep_null(*)) AS org_withdrawals,
ARRAY_AGG(object_delete(object_construct_keep_null(*),'ID')) AS del_withdrawals,
ARRAY_AGG(object_construct_keep_null('amount', w.amount, 'status', w.status)) AS add_withdrawals
FROM wt as w
GROUP BY 1;
ID
ORG_WITHDRAWALS
DEL_WITHDRAWALS
ADD_WITHDRAWALS
001
[ { "AMOUNT": 200, "ID": "001", "STATUS": "accept" }, { "AMOUNT": 100, "ID": "001", "STATUS": "accept" } ]
[ { "AMOUNT": 200, "STATUS": "accept" }, { "AMOUNT": 100, "STATUS": "accept" } ]
[ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" } ]
003
[ { "AMOUNT": 200, "ID": "003", "STATUS": "accept" } ]
[ { "AMOUNT": 200, "STATUS": "accept" } ]
[ { "amount": 200, "status": "accept" } ]
002
[ { "AMOUNT": 200, "ID": "002", "STATUS": "accept" }, { "AMOUNT": 100, "ID": "002", "STATUS": "accept" } ]
[ { "AMOUNT": 200, "STATUS": "accept" }, { "AMOUNT": 100, "STATUS": "accept" } ]
[ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" } ]
如果你想控制你的输出对象的大小写,我会去 OBJECT_CONSTRUST 方向,因为你有独立的控制权。但是,如果您担心 table 会改变形状,或者有很多列,* - ID
方法可能是最简单的方法,尽管性能较低。
我是 Snowflake 的新手,我正在尝试编写一个 SQL 查询来创建一个 JSON 对象,同时从输出中排除特定列
table: 莱克斯
id | Amount | status |
---|---|---|
001 | 200 | accept |
001 | 100 | accept |
002 | 200 | accept |
002 | 100 | accept |
003 | 200 | accept |
到目前为止我的代码
With wt as (
Select *
FROM lex
),
-------Convert to JSON------
wt_json as (
select id,
ARRAY_AGG(object_construct_keep_null(*)) withdrawals
from wt
Group by id
)
select * from wt_json
这会产生类似于此的输出
id | withdrawals |
---|---|
01 | [{id: 01, amount :200, status: accept},{id: 01, amount :100,status: accept}] |
02 | [{id: 02, amount :200, status: accept},{id: 02, amount :100,status: accept}] |
03 | [{id: 03, amount :200, status: accept}] |
但是,我试图排除 JSON 对象中的 ID。
我想要达到的目标
id | withdrawals |
---|---|
01 | [{ amount :200, status: accept},{ amount :100,status: accept}] |
02 | [{ amount :200, status: accept},{ amount :100,status: accept}] |
03 | [{ amount :200, status: accept}] |
Returns an object containing the contents of the input (i.e.source) object with one or more keys removed.
With wt as (
Select *
FROM lex
),
-------Convert to JSON------
wt_json as (
select id,
ARRAY_AGG(OBJECT_DELETE(object_construct_keep_null(*), 'id')) withdrawals
from wt
Group by id
)
select * from wt_json
您正在 object_construct_keep_null
函数中使用 *。这意味着该对象是从所有可用列构造的。如果您不想要这个,那么请以 'key', value
的形式指定您想要的每一列。您可以单独包含“id”列来实现您想要的:
WITH src AS (
SELECT '01' AS "id", 200 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '01' AS "id", 100 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '02' AS "id", 200 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '02' AS "id", 100 AS "amount", 'accept' AS "status"
UNION ALL
SELECT '03' AS "id", 200 AS "amount", 'accept' AS "status"
)
SELECT
"id"
, array_agg(
object_construct_keep_null(
'amount', "amount",
'status', "status"
)
) AS "withdrawals"
FROM src
GROUP BY "id"
结果:
id withdrawals
---------------------------------------------------------------------------------------------------
01 [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" }]
02 [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" }]
03 [ { "amount": 200, "status": "accept" }]
所以 OBJECT_DELETE 的问题是 id 必须与密钥大小写相同,因为 JSON 区分大小写,而 SQL 不区分大小写,因此默认情况下,它全部变为大写,因此在我下面的代码中,我允许 id
为 non-qouted,对于 OBJECT_DELETE 命令,它实际上是 'ID'
。
因此:
WITH wt AS (
SELECT * FROM VALUES
('001', 200, 'accept'),
('001', 100, 'accept'),
('002', 200, 'accept'),
('002', 100, 'accept'),
('003', 200, 'accept')
v(id, amount, status)
)
SELECT w.id,
ARRAY_AGG(object_construct_keep_null(*)) AS org_withdrawals,
ARRAY_AGG(object_delete(object_construct_keep_null(*),'ID')) AS del_withdrawals,
ARRAY_AGG(object_construct_keep_null('amount', w.amount, 'status', w.status)) AS add_withdrawals
FROM wt as w
GROUP BY 1;
ID | ORG_WITHDRAWALS | DEL_WITHDRAWALS | ADD_WITHDRAWALS |
---|---|---|---|
001 | [ { "AMOUNT": 200, "ID": "001", "STATUS": "accept" }, { "AMOUNT": 100, "ID": "001", "STATUS": "accept" } ] | [ { "AMOUNT": 200, "STATUS": "accept" }, { "AMOUNT": 100, "STATUS": "accept" } ] | [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" } ] |
003 | [ { "AMOUNT": 200, "ID": "003", "STATUS": "accept" } ] | [ { "AMOUNT": 200, "STATUS": "accept" } ] | [ { "amount": 200, "status": "accept" } ] |
002 | [ { "AMOUNT": 200, "ID": "002", "STATUS": "accept" }, { "AMOUNT": 100, "ID": "002", "STATUS": "accept" } ] | [ { "AMOUNT": 200, "STATUS": "accept" }, { "AMOUNT": 100, "STATUS": "accept" } ] | [ { "amount": 200, "status": "accept" }, { "amount": 100, "status": "accept" } ] |
如果你想控制你的输出对象的大小写,我会去 OBJECT_CONSTRUST 方向,因为你有独立的控制权。但是,如果您担心 table 会改变形状,或者有很多列,* - ID
方法可能是最简单的方法,尽管性能较低。