如何从表中选择带有 oracle sql 中的 group by 子句的嵌套 json 对象?
Posted
技术标签:
【中文标题】如何从表中选择带有 oracle sql 中的 group by 子句的嵌套 json 对象?【英文标题】:How can I select a nested json object with a group by clause in oracle sql from a table? 【发布时间】:2020-12-02 07:57:40 【问题描述】:假设我有以下声明:
WITH t AS
(
SELECT 'A' AS level_0, 'A1' AS level_1_1, 'object_1' AS level_1_2, 'A11' AS level_2_1, 'B11' AS level_2_2 FROM dual
UNION ALL
SELECT 'A' AS level_0, 'A1' AS level_1_1, 'object_1' AS level_1_2, 'A12' AS level_2_1, 'B12' AS level_2_2 FROM dual
UNION ALL
SELECT 'A' AS level_0, 'A1' AS level_1_1, 'object_1' AS level_1_2, 'A13' AS level_2_1, 'B13' AS level_2_2 FROM dual
UNION ALL
SELECT 'A' AS level_0, 'A1' AS level_1_1, 'object_1' AS level_1_2, 'A14' AS level_2_1, 'B14' AS level_2_2 FROM dual
UNION ALL
SELECT 'B' AS level_0, 'A1' AS level_1_1, 'object_2' AS level_1_2, 'A11' AS level_2_1, 'B15' AS level_2_2 FROM dual
UNION ALL
SELECT 'B' AS level_0, 'A1' AS level_1_1, 'object_2' AS level_1_2, 'A12' AS level_2_1, 'B16' AS level_2_2 FROM dual
UNION ALL
SELECT 'B' AS level_0, 'A1' AS level_1_1, 'object_2' AS level_1_2, 'A13' AS level_2_1, 'B17' AS level_2_2 FROM dual
)
SELECT * FROM t
我想要的输出如下所示:
+---------+---------------------------------------------------------------------------------+
| Level 0 | JSON |
+---------+---------------------------------------------------------------------------------+
| A | "level_1_1":"A1","object_1":"A11":"B11","A12":"B12","A13":"B13","A14":"B14" |
| B | "level_1_1":"A1","object_2":"A11":"B15","A12":"B16","A13":"B17" |
+---------+---------------------------------------------------------------------------------+
如何使用 select 语句获得此输出?
非常感谢您的帮助!
【问题讨论】:
可能是useful 【参考方案1】:JSON_OBJECT()
和 JSON_OBJECTAGG()
函数可以与适当的分组一起使用,例如
SELECT level_0,
JSON_OBJECT(
'level_1_1' VALUE level_1_1,
level_1_2 VALUE JSON_OBJECTAGG(level_2_1 VALUE level_2_2)
)
AS "Result JSON"
FROM t
GROUP BY level_1_2, level_1_1, level_0
Demo
【讨论】:
【参考方案2】:您可以使用GROUP BY
、LISTAGG
和concatenation
,如下所示:
SQL> with t as(
2 select 'A' as level_0, 'A1' as level_1_1, 'object_1' as level_1_2, 'A11' as level_2_1, 'B11' as level_2_2 from dual union all
3 select 'A' as level_0, 'A1' as level_1_1, 'object_1' as level_1_2, 'A12' as level_2_1, 'B12' as level_2_2 from dual union all
4 select 'A' as level_0, 'A1' as level_1_1, 'object_1' as level_1_2, 'A13' as level_2_1, 'B13' as level_2_2 from dual union all
5 select 'A' as level_0, 'A1' as level_1_1, 'object_1' as level_1_2, 'A14' as level_2_1, 'B14' as level_2_2 from dual union all
6 select 'B' as level_0, 'A1' as level_1_1, 'object_2' as level_1_2, 'A11' as level_2_1, 'B15' as level_2_2 from dual union all
7 select 'B' as level_0, 'A1' as level_1_1, 'object_2' as level_1_2, 'A12' as level_2_1, 'B16' as level_2_2 from dual union all
8 select 'B' as level_0, 'A1' as level_1_1, 'object_2' as level_1_2, 'A13' as level_2_1, 'B17' as level_2_2 from dual
9 )
10 select LEVEL_0,
11 '"level_1_1":"'|| level_1_1 || '","'||level_1_2 ||'":'
12 || LISTAGG('"' || level_2_1 || '":"' || level_2_2 || '"', ',')
13 WITHIN GROUP (ORDER BY level_2_1, level_2_2)
14 || '' AS JSON
15 from t
16 GROUP BY LEVEL_0, level_1_1, level_1_2;
LEVEL_0 JSON
---------- -------------------------------------------------------------------------------
A "level_1_1":"A1","object_1":"A11":"B11","A12":"B12","A13":"B13","A14":"B14"
B "level_1_1":"A1","object_2":"A11":"B15","A12":"B16","A13":"B17"
SQL>
【讨论】:
非常感谢您的解决方案。我认为 listagg 函数中应该有一个分隔符参数,例如 LISTAGG('"' || level_2_1 || '":"' || level_2_2 || '"',',')以上是关于如何从表中选择带有 oracle sql 中的 group by 子句的嵌套 json 对象?的主要内容,如果未能解决你的问题,请参考以下文章