SELECT key1, key2, JSON_ARRAYAGG(foo) foo, JSON_ARRAYAGG(bar) bar FROM (
select 1 as key1, 2 as key2, '1.0' as foo, 'A' as bar from dual
UNION
select 1, 2, '2.0' , 'A' as bar from dual
UNION
select 3, 4, '2.0' , 'A' as bar from dual
UNION
select 3, 4, '2.0' , 'B' as bar from dual
UNION
select 3, 4, '2.0' , 'B' as bar from dual) z
GROUP BY key1, key2
查询返回如下结果:
1 2 ["1.0","2.0"] ["A","A"]
3 4 ["2.0","2.0"] ["A","B"]
我在期待
1 2 ["1.0","2.0"] ["A"]
3 4 ["2.0"] ["A","B"]
JSON_ARRAYAGG 似乎不支持 DISTINCT,有什么建议吗?
是的,那还没有实现。解决方法是提前去重数据,eg
SQL> with x as (
2 select 1 as i, 'A' as j from dual union all select 1, 'A' from dual union all select 1, 'A' from dual
3 union all
4 select 2, 'D' from dual union all select 2, 'D' from dual union all select 2, 'E' from dual
5 union all
6 select 3, 'G' from dual union all select 3, 'H' from dual union all select 3, 'H' from dual
7 )
8 select x.i,
9 listagg(distinct x.j, ', ') within group (order by x.j) as X_LIST,
10 json_arrayagg( x.j order by x.j) as X_JSON
11 from x
12 group by x.i;
I X_LIST X_JSON
---------- ------------------------------ ------------------------------
1 A ["A","A","A"]
2 D, E ["D","D","E"]
3 G, H ["G","H","H"]
SQL>
SQL> with x as (
2 select 1 as i, 'A' as j from dual union all select 1, 'A' from dual union all select 1, 'A' from dual
3 union all
4 select 2, 'D' from dual union all select 2, 'D' from dual union all select 2, 'E' from dual
5 union all
6 select 3, 'G' from dual union all select 3, 'H' from dual union all select 3, 'H' from dual
7 )
8 select x.i,
9 listagg(distinct x.j, ', ') within group (order by x.j) as X_LIST,
10 json_arrayagg( x.j order by x.j) as X_JSON
11 from ( select distinct i,j from x order by i,j ) x
12 group by x.i;
I X_LIST X_JSON
---------- ------------------------------ ------------------------------
1 A ["A"]
2 D, E ["D","E"]
3 G, H ["G","H"]
除了 Connor 写的替代解决方法之外
aggregate function + row_number for de-duplication (
rn
可以移动到 where clause
而不是 decode
视情况而定,但在这种情况下 distinct
更可取)
select
x.i,
listagg(decode(rn, 1, x.j), ', ') within group (order by x.j) as X_LIST,
json_arrayagg(decode(rn, 1, x.j) order by x.j) as X_JSON
from (select x.*, row_number() over (partition by i, j order by '') rn from x) x
group by x.i;
相关标量中的嵌套聚合(请记住,每个相关标量实际上是一个隐式
join
)
select
xx.*,
(select listagg(min(x.j), ', ') within group (order by x.j) from x where x.i = xx.i group by x.j) as X_LIST,
(select json_arrayagg(min(x.j) order by x.j) from x where x.i = xx.i group by x.j) as X_LIST
from (select distinct i from x) xx;