您可能需要通过几个步骤来打破它。
首先,一个与您的相似的基表。
db2 => SELECT * FROM PROD_T
ID ITEM ITEMSCORE STAGE PRODUCT URL SCORE
----------- -------------------- --------- ----- -------------------- -------------------- -------
2078012 cos -0,1334 0,5 Language https:// 0,0190
2078012 build -0,2585 0,5 Notification https:// 0,1690
2100000 alpha -0,1334 0,5 Letter https:// 0,0190
2100000 beta -0,2585 0,5 anouncement https:// 0,1690
第 1 步:创建基本级别的 json 对象
select id, item,
JSON_OBJECT('item' value item,
'itemScore' value itemScore,
'stage' value stage,
'reco' VALUE JSON_OBJECT('product' value product,
'url' value url ,
'score' value score
FORMAT JSON )
FORMAT JSON ABSENT ON NULL
RETURNING VARCHAR(200) FORMAT JSON) ITEM_JSON
FROM PROD_T
ID ITEM ITEM_JSON
----------- -------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2078012 cos {"item":"cos","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Language","url":"https:\/\/","score":0.0190}}
2078012 build {"item":"build","itemScore":-0.2585,"stage":0.5,"reco":{"product":"Notification","url":"https:\/\/","score":0.1690}}
2100000 alpha {"item":"alpha","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Letter","url":"https:\/\/","score":0.0190}}
2100000 beta {"item":"beta","itemScore":-0.2585,"stage":0.5,"reco":{"product":"anouncement","url":"https:\/\/","score":0.1690}}
第 2 步:按 id 分组,并将对象聚合到一个数组中。
WITH BASE AS (
select id, item,
JSON_OBJECT('item' value item,
'itemScore' value itemScore,
'stage' value stage,
'reco' VALUE JSON_OBJECT('product' value product,
'url' value url ,
'score' value score
FORMAT JSON )
FORMAT JSON ABSENT ON NULL
RETURNING VARCHAR(200) FORMAT JSON) ITEM_JSON
FROM PROD_T )
SELECT ID, JSON_ARRAY ( LISTAGG( ITEM_JSON , ', ') WITHIN GROUP (ORDER BY ITEM) FORMAT JSON ) ITEMS_ARRAY
FROM BASE GROUP BY ID
ID ITEMS_ARRAY
----------- --------------------------------------------------
2078012 [{"item":"build","itemScore":-0.2585,"stage":0.5,"reco":{"product":"Notification","url":"https:\/\/","score":0.1690}}, {"item":"cos","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Language","url":"https:\/\/","score":0.0190}}]
2100000 [{"item":"alpha","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Letter","url":"https:\/\/","score":0.0190}}, {"item":"beta","itemScore":-0.2585,"stage":0.5,"reco":{"product":"anouncement","url":"https:\/\/","score":0.1690}}]
第 3 步:为每个 id 行创建整个 json_object
WITH BASE AS (
select id, item,
JSON_OBJECT('item' value item,
'itemScore' value itemScore,
'stage' value stage,
'reco' VALUE JSON_OBJECT('product' value product,
'url' value url ,
'score' value score
FORMAT JSON )
FORMAT JSON ABSENT ON NULL
RETURNING VARCHAR(200) FORMAT JSON) ITEM_JSON
FROM PROD_T )
SELECT JSON_OBJECT ( KEY 'id' VALUE ID ,
KEY 'itens' VALUE
JSON_ARRAY ( LISTAGG( ITEM_JSON , ', ') WITHIN GROUP (ORDER BY ITEM) FORMAT JSON )
FORMAT JSON ) json_objects
FROM BASE GROUP BY ID
json_objects
-----------------------------------------------------------------------------------------------------------------------------------
{"id":2078012,"itens":[{"item":"build","itemScore":-0.2585,"stage":0.5,"reco":{"product":"Notification","url":"https:\/\/","score":0.1690}}, {"item":"cos","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Language","url":"https:\/\/","score":0.0190}}]}
{"id":2100000,"itens":[{"item":"alpha","itemScore":-0.1334,"stage":0.5,"reco":{"product":"Letter","url":"https:\/\/","score":0.0190}}, {"item":"beta","itemScore":-0.2585,"stage":0.5,"reco":{"product":"anouncement","url":"https:\/\/","score":0.1690}}]}
第 4 步:id 的完整 json doc 数组
下面的查询应该可以工作,
WITH BASE AS (
select id, item,
JSON_OBJECT('item' value item,
'itemScore' value itemScore,
'stage' value stage,
'reco' VALUE JSON_OBJECT('product' value product,
'url' value url ,
'score' value score
FORMAT JSON )
FORMAT JSON ABSENT ON NULL
RETURNING VARCHAR(200) FORMAT JSON) ITEM_JSON
FROM PROD_T ),
PROD_OBJS AS (
SELECT JSON_OBJECT ( KEY 'id' VALUE ID ,
KEY 'itens' VALUE
JSON_ARRAY ( LISTAGG( ITEM_JSON , ', ') WITHIN GROUP (ORDER BY ITEM) FORMAT JSON )
FORMAT JSON ) json_objects
FROM BASE GROUP BY ID )
SELECT JSON_ARRAY (select json_objects FROM PROD_OBJS format json) FROM SYSIBM.SYSDUMMY1
但是,在我的系统 (DB2 v11.5.0.1077) 中,它因一些内部编译错误而失败:
SQL0901N 由于数据库,SQL 语句或命令失败
系统错误。 (原因“意外的 agg opparm”。) SQLSTATE=58004
但是,如果您遇到同样的情况,您可以将 step3 的输出具体化到一个临时表中,并从中执行最终的数组。
DECLARE GLOBAL TEMPORARY TABLE prod_json_objcts AS (
WITH BASE AS (
select id, item,
JSON_OBJECT('item' value item,
'itemScore' value itemScore,
'stage' value stage,
'reco' VALUE JSON_OBJECT('product' value product,
'url' value url ,
'score' value score
FORMAT JSON )
FORMAT JSON ABSENT ON NULL
RETURNING VARCHAR(200) FORMAT JSON) ITEM_JSON
FROM PROD_T )
SELECT JSON_OBJECT ( KEY 'id' VALUE ID ,
KEY 'itens' VALUE
JSON_ARRAY ( LISTAGG( ITEM_JSON , ', ') WITHIN GROUP (ORDER BY ITEM) FORMAT JSON )
FORMAT JSON ) json_objects
FROM BASE GROUP BY ID
) WITH DATA
SELECT JSON_ARRAY (select json_objects FROM session.prod_json_objcts format json) FROM SYSIBM.SYSDUMMY1
生成最终的 json 数组:
[{"id":2078012,
"itens":[
{"item":"build",
"itemScore":-0.2585,
"stage":0.5,
"reco":{"product":"Notification",
"url":"https:\/\/",
"score":0.1690}},
{"item":"cos",
"itemScore":-0.1334,
"stage":0.5,
"reco":{"product":"Language",
"url":"https:\/\/",
"score":0.0190}}
]
},
{"id":2100000,
"itens":[
{"item":"alpha",
"itemScore":-0.1334,
"stage":0.5,
"reco":{"product":"Letter",
"url":"https:\/\/",
"score":0.0190}},
{"item":"beta",
"itemScore":-0.2585,
"stage":0.5,
"reco":{"product":"anouncement",
"url":"https:\/\/",
"score":0.1690}}
]
}
]