簡體   English   中英

如何在 case 語句中正確使用 listagg

[英]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  

演示

這是一個選項,它使用多個自聯接。

  • 第 1 - 14 行代表您的樣本數據
  • anima CTE 是為了簡化代碼; 最好將它放在一個表中(即使它是 CTE)而不是使用CASE
  • 最終結果,第 #24 - 34 行,連接動物名稱
    • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM