我找到了关于comma separated list of values in Oracle的非常好的文章。
我想尝试一下,但是有两列而不是一列,就像数据一样:
+---+---------+---------+
| 1 | a, b, c | A, B |
| 2 | a, b | A, B, C |
+---+---------+---------+
我想得到结果:
over
我遇到的第一个问题是使用ORA-00979: not a GROUP BY expression
部分......
甚至,当我看到documentation和多个例子时,f.e。 here
我无法解决with demotable as
(
select 1 v1, 'a' v2, 'A' v3 from dual union all
select 1 v1, 'a' v2, 'B' v3 from dual union all
select 1 v1, 'b' v2, 'A' v3 from dual union all
select 1 v1, 'b' v2, 'B' v3 from dual union all
select 1 v1, 'c' v2, 'A' v3 from dual union all
select 1 v1, 'c' v2, 'B' v3 from dual union all
select 2 v1, 'a' v2, 'A' v3 from dual union all
select 2 v1, 'a' v2, 'B' v3 from dual union all
select 2 v1, 'a' v2, 'C' v3 from dual union all
select 2 v1, 'b' v2, 'A' v3 from dual union all
select 2 v1, 'b' v2, 'B' v3 from dual union all
select 2 v1, 'b' v2, 'C' v3 from dual
)
select v1
, LISTAGG (
v3, ', '
) within group (
order by v3
) over (
partition by v1
) AS v3_list
from demotable
group by v1
;
问题:
with demotable as ( ... )
select v1
, LISTAGG (
v2, ', '
) within group (
order by v2
) AS v2_list
, LISTAGG (
v3, ', '
) within group (
order by v3
) AS v3_list
from demotable
group by v1
;
基于其他例子的应该有效。
我想到的第一个解决方案是无法正常工作
+---+------------------+------------------+
| 1 | a, a, b, b, c, c | A, A, A, B, B, B |
| 2 | a, a, a, b, b, b | A, A, B, B, C, C |
+---+------------------+------------------+
因为它返回:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
我的Oracle版本是12c。
with demotable as ( ... )
select v1
, LISTAGG (
v2, ', '
) within group (
order by v2
) AS v2_list
, v3_list
from (
select v1
, v2
, LISTAGG (
v3, ', '
) within group (
order by v3
) AS v3_list
from demotable
group by v1, v2
) group by v1, v3_list
;
我发现只选择了选择的丑陋解决方案:
group by
删除其评论的人建议对所有列使用with demotable as ( ... )
select distinct v1
, LISTAGG (
v2, ', '
) WITHIN GROUP (
ORDER BY v2
) over (
partition by v1, v3
) AS v2_list
, LISTAGG (
v3, ', '
) WITHIN GROUP (
ORDER BY v3
) over (
partition by v1, v2
) AS v2_list
from demotable
group by v1, v2, v3
;
,这会引导我找到这个解决方案:
distinct
但如果没有必要,我不是{{1}}的粉丝。
答案 0 :(得分:1)
使用这个非常好的answer
select v1
,RTRIM(
REGEXP_REPLACE(
(listagg(v3,',') WITHIN GROUP (ORDER BY v3) ),
'([^,]*)(,\1)+($|,)',
'\1\3'),
',') as v3group
,RTRIM(
REGEXP_REPLACE(
(listagg(v2,',') WITHIN GROUP (ORDER BY v2) ),
'([^,]*)(,\1)+($|,)',
'\1\3'),
',') as v2group
from demotable
GROUP BY v1
;
答案 1 :(得分:1)
假设我正确理解您的要求,我认为这符合您的要求:
with demotable as (select 1 v1, 'a' v2, 'A' v3 from dual union all
select 1 v1, 'a' v2, 'B' v3 from dual union all
select 1 v1, 'b' v2, 'A' v3 from dual union all
select 1 v1, 'b' v2, 'B' v3 from dual union all
select 1 v1, 'c' v2, 'A' v3 from dual union all
select 1 v1, 'c' v2, 'B' v3 from dual union all
select 2 v1, 'a' v2, 'A' v3 from dual union all
select 2 v1, 'a' v2, 'B' v3 from dual union all
select 2 v1, 'a' v2, 'C' v3 from dual union all
select 2 v1, 'b' v2, 'A' v3 from dual union all
select 2 v1, 'b' v2, 'B' v3 from dual union all
select 2 v1, 'b' v2, 'C' v3 from dual),
res as (select v1,
case when row_number() over (partition by v1, v2 order by v3) = 1 then v2 end v2,
case when row_number() over (partition by v1, v3 order by v2) = 1 then v3 end v3
from demotable)
select v1,
listagg(v2, ', ') within group (order by v2) v2_list,
listagg(v3, ', ') within group (order by v2) v3_list
from res
group by v1;
V1 V2_LIST V3_LIST
---------- ---------- ----------
1 a, b, c A, B
2 a, b A, B, C
res子查询只需要在v2和v3列中显示每个值的一个实例,这样就可以将一个不同值列表传递给每个listagg。