Oracle 列轉行函數 Listagg()


Oracle 列轉行函數 Listagg()

 

這是一個Oracle的列轉行函數:LISTAGG()

 

先看示例代碼:

Sql代碼 複製代碼 收藏代碼
  1. with temp as(  
  2.   select 'China' nation ,'Guangzhou' city from dual union all  
  3.   select 'China' nation ,'Shanghai' city from dual union all  
  4.   select 'China' nation ,'Beijing' city from dual union all  
  5.   select 'USA' nation ,'New York' city from dual union all  
  6.   select 'USA' nation ,'Bostom' city from dual union all  
  7.   select 'Japan' nation ,'Tokyo' city from dual   
  8. )  
  9. select nation,listagg(city,',') within GROUP (order by city)  
  10. from temp  
  11. group by nation  
with temp as(
  select 'China' nation ,'Guangzhou' city from dual union all
  select 'China' nation ,'Shanghai' city from dual union all
  select 'China' nation ,'Beijing' city from dual union all
  select 'USA' nation ,'New York' city from dual union all
  select 'USA' nation ,'Bostom' city from dual union all
  select 'Japan' nation ,'Tokyo' city from dual 
)
select nation,listagg(city,',') within GROUP (order by city)
from temp
group by nation

 這是最基礎的用法:

LISTAGG(XXX,XXX) WITHIN GROUP( ORDER BY XXX)

 

用法就像聚合函數一樣,通過Group by語句,把每個Group的一個字段,拼接起來。

非常方便。

 

同樣是聚合函數,還有一個高級用法:

就是over(partition by XXX)

也就是說,在你不實用Group by語句時候,也可以使用LISTAGG函數:

Sql代碼 複製代碼 收藏代碼
  1. with temp as(  
  2.   select 500 population, 'China' nation ,'Guangzhou' city from dual union all  
  3.   select 1500 population, 'China' nation ,'Shanghai' city from dual union all  
  4.   select 500 population, 'China' nation ,'Beijing' city from dual union all  
  5.   select 1000 population, 'USA' nation ,'New York' city from dual union all  
  6.   select 500 population, 'USA' nation ,'Bostom' city from dual union all  
  7.   select 500 population, 'Japan' nation ,'Tokyo' city from dual   
  8. )  
  9. select population,  
  10.        nation,  
  11.        city,  
  12.        listagg(city,',') within GROUP (order by city) over (partition by nation) rank  
  13. from temp  
with temp as(
  select 500 population, 'China' nation ,'Guangzhou' city from dual union all
  select 1500 population, 'China' nation ,'Shanghai' city from dual union all
  select 500 population, 'China' nation ,'Beijing' city from dual union all
  select 1000 population, 'USA' nation ,'New York' city from dual union all
  select 500 population, 'USA' nation ,'Bostom' city from dual union all
  select 500 population, 'Japan' nation ,'Tokyo' city from dual 
)
select population,
       nation,
       city,
       listagg(city,',') within GROUP (order by city) over (partition by nation) rank
from temp

 

總結:LISTAGG()把它當作SUM()函數來使用就可以了。


listagg
在oracle 11g release 2 版本中新增的listagg函數,listagg是一個實現字符串聚合的oracle內建函數;
listagg(column,'分隔符') within group (order by column) over(partition by column)
分隔符可以爲空,
order by必選項,可以order by null

(1)select status,  listagg(risk_id, ',') within group (order by risk_id) from rp_risk group by status;
以status分組,將risk_id全部合併顯示在一行
(2)與許多的聚合函數類似,listagg通過加上over()子句可以實現分析功能
select risk_id, status, listagg(risk_id, ',') within group (order by risk_id) over(partition by status) from rp_risk;
選出與當前risk_id在同一個部門的所有risk_id併合並字符串
(3)listagg聚合的結果列大小限制在varchar2類型的最大值內(比如4000);
(4)合併字符串也可以用wm_concat(column_name),所有版本的oracle都可以用這個函數
 listagg()是oracle 11g release 2纔有;
(5)參考鏈接

http://xpchild.blog.163.com/blog/static/10180985920108485721969/

 

Sql代碼 複製代碼 收藏代碼
  1. --listagg(合併多行的值爲字符串,只用一列來顯示)  
  2. select status, count(*),  listagg(risk_id, ',') within group (order by risk_id) from rp_risk group by status;  
  3. select risk_id, status, listagg(risk_id, ',') within group (order by risk_id) over(partition by status) from rp_risk;  
  4. select risk.risk_id, listagg(officer.last_name || ',' || officer.first_name, '; ') within group(order by nullfrom rp_risk risk, rp_risk_area_ref re, rp_risk_area area, rp_risk_officer officer   
  5. where risk.risk_id = re.risk_id  
  6. and re.risk_area_id = area.risk_area_id(+)  
  7. and area.risk_officer_id = officer.risk_officer_id(+)  
  8. group by risk.risk_id;  
  9.   
  10.   
  11. --pivot(行專列,將多行的值改爲多列顯示)(for in的那個column,是某個列的值,也就是將某個列的值作爲新的列的column,這個column下邊的值好像只能來自一列)  
  12. select * from   
  13.   (select risk.risk_id, re.risk_area_order, officer.last_name || ',' || officer.first_name fullname   
  14.   from rp_risk risk, rp_risk_area_ref re, rp_risk_area area, rp_risk_officer officer   
  15.   where risk.risk_id = re.risk_id  
  16.   and re.risk_area_id = area.risk_area_id(+)  
  17.   and area.risk_officer_id = officer.risk_officer_id(+) order by risk.risk_id desc, re.risk_area_order)  
  18.   pivot(max(fullname) for risk_area_order in (1 primaryOfficer, 2 addtionalOffcier1, 3 addtionalOffcier2)) order by risk_id desc;  
  19.   
  20.   
  21. --decode(行專列,將多行的值改爲多列顯示)(decode的那個column,是某個列的值,也就是將某個列的值作爲新的列的column,MAX聚集函數也可以用sum、min、avg等其他聚集函數替代)  
  22. select risk_id,   
  23. --max(decode(risk_area_order, 1, fullname)) primaryOfficer,  
  24. --max(decode(risk_area_order, 2, fullname)) addtionalOffcier1,  
  25. --max(decode(risk_area_order, 3, fullname)) addtionalOffcier1  
  26. min(decode(risk_area_order, 1, fullname)) primaryOfficer,  
  27. min(decode(risk_area_order, 2, fullname)) addtionalOffcier1,  
  28. min(decode(risk_area_order, 3, fullname)) addtionalOffcier1  
  29. from   
  30.   (select risk.risk_id, re.risk_area_order, officer.last_name || ',' || officer.first_name fullname from rp_risk risk, rp_risk_area_ref re, rp_risk_area area, rp_risk_officer officer   
  31.   where risk.risk_id = re.risk_id  
  32.   and re.risk_area_id = area.risk_area_id(+)  
  33.   and area.risk_officer_id = officer.risk_officer_id(+) order by risk.risk_id, re.risk_area_order)  
  34. group by risk_id order by risk_id;  

發佈了10 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章