Oracle的行轉列和列轉行

2021-08-13 07:53:39 字數 1732 閱讀 2827

用scott使用者自帶的emp表作為例子,查詢每個部門下所有的雇員的名字:

select deptno,wm_concat(ename) from emp group by deptno;
查詢結果為:

oracle新增的listagg函式也是對字串的行列轉換,但是功能比wm_concat功能更加強大,它可以和開窗函式over()一起使用

listagg的語法:listagg( [欄位名,分隔符]) within group (order by ) [over (partition by )]

同樣以scott使用者自帶的emp表做為例子,還是查詢每個部門下所有雇員的名字,注意group裡面的order by 不能為空:

按雇員的姓名排序

select deptno,listagg(ename,',') within group (order by ename) from emp group by deptno;

listagg函式還可以和over()開窗函式一起使用:

select deptno,listagg(ename,',') within group (order by ename) over(partition by deptno) from emp;
oracle中我們可以使用case when end 或者 decode 函式做到行列互轉的功能,這有的優點是使用範圍廣,但是編寫和維護麻煩。而oracle11g中的pivot函式可以很簡單的實現行列互轉,但是使用範圍有限制。

還是使用scott使用者下的emp用來做資料來源,現在需要統計每個工作在每個部門的工資總和,乙個部門用一列表示:

先使用case when end來實現:

select job,

sum(case when deptno = 10 then sal end) as 部門10工資,

sum(case when deptno = 20 then sal end) as 部門20工資,

sum(case when deptno = 30 then sal end) as 部門30工資

from emp group by job

使用pivot函式實現:

select * from (select job,sal,deptno from emp) pivot(sum(sal) for deptno in (10 as d10,20 as d20,30 as d30))
可以發現pivot函式簡單更多,而且更容易擴充套件,假設現在還要把獎金也統計進去,那麼用case when end 就需要新增三行,而pivot只需新增乙個字段

select * from (select job,sal,deptno,comm from emp) pivot(sum(sal) as s,sum(comm) as c for deptno in (10 as d10,20 as d20,30 as d30))
pivot函式的語法:pivot(聚合函式 as 總的別名... for 字段 in (欄位a as 別名1 ,欄位b as 別名2...)

通過檢視sql語句的plan,我們發現實際上pivot實際上也是使用的case when end,只是寫法更簡單了。

Oracle行轉列和列轉行

1.1 初始測試資料 表結構 test tb grade sql 1 create table test tb grade 2 3 id number 10 not null,4 user name varchar2 20 char 5 course varchar2 20 char 6 score...

Oracle行轉列和列轉行

一 行轉列 1.1 初始測試資料 表結構 test tb grade sql 1 create table test tb grade 2 3 id number 10 not null,4 user name varchar2 20 char 5 course varchar2 20 char 6...

Oracle行轉列和列轉行

一 行轉列 1.1 初始測試資料 表結構 test tb grade sql 1 create table test tb grade 2 3 id number 10 not null,4 user name varchar2 20 char 5 course varchar2 20 char 6...