如何在 case 语句中正确使用 listagg
How to use listagg properly with case statements
我正在尝试使用 listagg,但我得到了错误的输出。通常,我会分别使用每个 case 语句,但我将如何使用 listagg?
Table答:
JAN FEB MAR APR Tag
C 102
D T 100
D 101
C D B T 103
Table乙:
Name Tag
Ally 100
Ben 101
Missy 102
Noah 103
期望的输出:
Ally Dog,Turtle
Ben Dog
Missy Chicken
Noah Chicken,Dog,Bird,Turtle
我尝试的(错误的)代码:
select listagg(
nvl(
case when a.jan = 'C' then 'Chicken'
when a.feb = 'D' then 'Dog'
when a.mar = 'B' then 'Bird'
when a.apr = 'T' then 'Turtle'
end,','),'none')
within group (order by a.tag)
from a where a.tag = b.tag
您可以通过在子查询中逆透视来构建查询:
select b.Name, a.*
from b
join
(
select tag, listagg( case
when val = 'C' then
'Chicken'
when val = 'D' then
'Dog'
when val = 'B' then
'Bird'
when val = 'T' then
'Turtle'
end,',') within group (order by 1) as animals
from a
unpivot ( val for name in (jan as 'JAN', feb as 'FEB', mar as 'MAR', apr as 'APR') )
group by tag ) a
on b.tag = a.tag
order by a.tag
这是一个选项,它使用多个自联接。
- 第 1 - 14 行代表您的样本数据
anima
CTE 是为了简化代码;最好将它放在 table 中(即使它是 CTE)而不是使用 CASE
- 最终结果,第 24 - 34 行,连接了动物名称
trim
+ regexp_replace
用于去掉多余的逗号
给你:
SQL> with
2 -- sample data
3 taba (jan, feb, mar, apr, tag) as
4 (select 'c' , null, null, null, 102 from dual union all
5 select null, 'd' , null, 't' , 100 from dual union all
6 select null, 'd' , null, null, 101 from dual union all
7 select 'c' , 'd' , 'b' , 't' , 103 from dual
8 ),
9 tabb (name, tag) as
10 (select 'ally' , 100 from dual union all
11 select 'ben' , 101 from dual union all
12 select 'missy', 102 from dual union all
13 select 'noah' , 103 from dual
14 ),
15 --
16 -- replace animal codes with their names
17 anima (code, name) as
18 (select 'c', 'chicken' from dual union all
19 select 'd', 'dog' from dual union all
20 select 'b', 'bird' from dual union all
21 select 't', 'turtle' from dual
22 )
23 -- the final result
24 select b.name,
25 trim(',' from regexp_replace(n1.name ||','|| n2.name ||','|| n3.name ||','|| n4.name,
26 '( *, *){2,}', ','
27 )
28 ) result
29 from tabb b join taba a on a.tag = b.tag
30 left join anima n1 on n1.code = a.jan
31 left join anima n2 on n2.code = a.feb
32 left join anima n3 on n3.code = a.mar
33 left join anima n4 on n4.code = a.apr
34 order by b.name;
NAME RESULT
----- ------------------------------
ally dog,turtle
ben dog
missy chicken
noah chicken,dog,bird,turtle
SQL>
with
-- sample data
taba (jan, feb, mar, apr, tag) as
(select 'c' , null, null, null, 102 from dual union all
select null, 'd' , null, 't' , 100 from dual union all
select null, 'd' , null, null, 101 from dual union all
select 'c' , 'd' , 'b' , 't' , 103 from dual
),
tabb (name, tag) as
(select 'ally' , 100 from dual union all
select 'ben' , 101 from dual union all
select 'missy', 102 from dual union all
select 'noah' , 103 from dual
),
tabab as (
--select a.tag, b.name, nvl(a.jan,'na') as jan, nvl(a.feb,'na') as feb, nvl(a.mar,'na') as mar, nvl(a.apr,'na') as apr
select
a.tag, b.name,
decode(a.jan,'b','bird','c','chicken','d','dog','t','turtle',null) as jan,
decode(a.feb,'b','bird','c','chicken','d','dog','t','turtle',null) as feb,
decode(a.mar,'b','bird','c','chicken','d','dog','t','turtle',null) as mar,
decode(a.apr,'b','bird','c','chicken','d','dog','t','turtle',null) as apr
from taba a
join tabb b
on a.tag = b.tag
)
select
name,
listagg(val,',') WITHIN GROUP (ORDER by decode(mon, 'JAN',1,'FEB',2,'MAR',3,'APR',4,null)) as listval
from tabab
unpivot
(
val
for mon in (jan,feb,mar,apr)
)
group by name
order by 1
;
我正在尝试使用 listagg,但我得到了错误的输出。通常,我会分别使用每个 case 语句,但我将如何使用 listagg?
Table答:
JAN FEB MAR APR Tag
C 102
D T 100
D 101
C D B T 103
Table乙:
Name Tag
Ally 100
Ben 101
Missy 102
Noah 103
期望的输出:
Ally Dog,Turtle
Ben Dog
Missy Chicken
Noah Chicken,Dog,Bird,Turtle
我尝试的(错误的)代码:
select listagg(
nvl(
case when a.jan = 'C' then 'Chicken'
when a.feb = 'D' then 'Dog'
when a.mar = 'B' then 'Bird'
when a.apr = 'T' then 'Turtle'
end,','),'none')
within group (order by a.tag)
from a where a.tag = b.tag
您可以通过在子查询中逆透视来构建查询:
select b.Name, a.*
from b
join
(
select tag, listagg( case
when val = 'C' then
'Chicken'
when val = 'D' then
'Dog'
when val = 'B' then
'Bird'
when val = 'T' then
'Turtle'
end,',') within group (order by 1) as animals
from a
unpivot ( val for name in (jan as 'JAN', feb as 'FEB', mar as 'MAR', apr as 'APR') )
group by tag ) a
on b.tag = a.tag
order by a.tag
这是一个选项,它使用多个自联接。
- 第 1 - 14 行代表您的样本数据
anima
CTE 是为了简化代码;最好将它放在 table 中(即使它是 CTE)而不是使用CASE
- 最终结果,第 24 - 34 行,连接了动物名称
trim
+regexp_replace
用于去掉多余的逗号
给你:
SQL> with
2 -- sample data
3 taba (jan, feb, mar, apr, tag) as
4 (select 'c' , null, null, null, 102 from dual union all
5 select null, 'd' , null, 't' , 100 from dual union all
6 select null, 'd' , null, null, 101 from dual union all
7 select 'c' , 'd' , 'b' , 't' , 103 from dual
8 ),
9 tabb (name, tag) as
10 (select 'ally' , 100 from dual union all
11 select 'ben' , 101 from dual union all
12 select 'missy', 102 from dual union all
13 select 'noah' , 103 from dual
14 ),
15 --
16 -- replace animal codes with their names
17 anima (code, name) as
18 (select 'c', 'chicken' from dual union all
19 select 'd', 'dog' from dual union all
20 select 'b', 'bird' from dual union all
21 select 't', 'turtle' from dual
22 )
23 -- the final result
24 select b.name,
25 trim(',' from regexp_replace(n1.name ||','|| n2.name ||','|| n3.name ||','|| n4.name,
26 '( *, *){2,}', ','
27 )
28 ) result
29 from tabb b join taba a on a.tag = b.tag
30 left join anima n1 on n1.code = a.jan
31 left join anima n2 on n2.code = a.feb
32 left join anima n3 on n3.code = a.mar
33 left join anima n4 on n4.code = a.apr
34 order by b.name;
NAME RESULT
----- ------------------------------
ally dog,turtle
ben dog
missy chicken
noah chicken,dog,bird,turtle
SQL>
with
-- sample data
taba (jan, feb, mar, apr, tag) as
(select 'c' , null, null, null, 102 from dual union all
select null, 'd' , null, 't' , 100 from dual union all
select null, 'd' , null, null, 101 from dual union all
select 'c' , 'd' , 'b' , 't' , 103 from dual
),
tabb (name, tag) as
(select 'ally' , 100 from dual union all
select 'ben' , 101 from dual union all
select 'missy', 102 from dual union all
select 'noah' , 103 from dual
),
tabab as (
--select a.tag, b.name, nvl(a.jan,'na') as jan, nvl(a.feb,'na') as feb, nvl(a.mar,'na') as mar, nvl(a.apr,'na') as apr
select
a.tag, b.name,
decode(a.jan,'b','bird','c','chicken','d','dog','t','turtle',null) as jan,
decode(a.feb,'b','bird','c','chicken','d','dog','t','turtle',null) as feb,
decode(a.mar,'b','bird','c','chicken','d','dog','t','turtle',null) as mar,
decode(a.apr,'b','bird','c','chicken','d','dog','t','turtle',null) as apr
from taba a
join tabb b
on a.tag = b.tag
)
select
name,
listagg(val,',') WITHIN GROUP (ORDER by decode(mon, 'JAN',1,'FEB',2,'MAR',3,'APR',4,null)) as listval
from tabab
unpivot
(
val
for mon in (jan,feb,mar,apr)
)
group by name
order by 1
;