[英]How to use listagg properly with case statements
我正在嘗試使用 listagg,但我得到了錯誤的 output。 通常,我會單獨使用每個 case 語句,但是我將如何使用 listagg 呢?
表 A:
JAN FEB MAR APR Tag
C 102
D T 100
D 101
C D B T 103
表 B:
Name Tag
Ally 100
Ben 101
Missy 102
Noah 103
所需的 Output:
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
這是一個選項,它使用多個自聯接。
anima
CTE 是為了簡化代碼; 最好將它放在一個表中(即使它是 CTE)而不是使用CASE
trim
+ regexp_replace
用於刪除多余的逗號這里是 go:
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
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.