這是一個Oracle的列轉行函數:LISTAGG()
先看示例代碼:
- 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
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函數:
- 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
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/
- --listagg(合併多行的值爲字符串,只用一列來顯示)
- select status, count(*), listagg(risk_id, ',') within group (order by risk_id) from rp_risk group by status;
- select risk_id, status, listagg(risk_id, ',') within group (order by risk_id) over(partition by status) from rp_risk;
- select risk.risk_id, listagg(officer.last_name || ',' || officer.first_name, '; ') within group(order by null) from rp_risk risk, rp_risk_area_ref re, rp_risk_area area, rp_risk_officer officer
- where risk.risk_id = re.risk_id
- and re.risk_area_id = area.risk_area_id(+)
- and area.risk_officer_id = officer.risk_officer_id(+)
- group by risk.risk_id;
- --pivot(行專列,將多行的值改爲多列顯示)(for in的那個column,是某個列的值,也就是將某個列的值作爲新的列的column,這個column下邊的值好像只能來自一列)
- select * from
- (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
- where risk.risk_id = re.risk_id
- and re.risk_area_id = area.risk_area_id(+)
- and area.risk_officer_id = officer.risk_officer_id(+) order by risk.risk_id desc, re.risk_area_order)
- pivot(max(fullname) for risk_area_order in (1 primaryOfficer, 2 addtionalOffcier1, 3 addtionalOffcier2)) order by risk_id desc;
- --decode(行專列,將多行的值改爲多列顯示)(decode的那個column,是某個列的值,也就是將某個列的值作爲新的列的column,MAX聚集函數也可以用sum、min、avg等其他聚集函數替代)
- select risk_id,
- --max(decode(risk_area_order, 1, fullname)) primaryOfficer,
- --max(decode(risk_area_order, 2, fullname)) addtionalOffcier1,
- --max(decode(risk_area_order, 3, fullname)) addtionalOffcier1
- min(decode(risk_area_order, 1, fullname)) primaryOfficer,
- min(decode(risk_area_order, 2, fullname)) addtionalOffcier1,
- min(decode(risk_area_order, 3, fullname)) addtionalOffcier1
- from
- (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
- where risk.risk_id = re.risk_id
- and re.risk_area_id = area.risk_area_id(+)
- and area.risk_officer_id = officer.risk_officer_id(+) order by risk.risk_id, re.risk_area_order)
- group by risk_id order by risk_id;