pivot、unpivot實現oracle行列轉換
11g之後,oracle增加了pivot和unpivot語句,可以很方便的完成行列轉換。
先來看看pivot的語法是
來看個例子,emp表中資料如下:
現在查詢各部門各工種的總薪水,如下:
現在需要將每個工種作為一列顯示就更一目瞭然,這就需要進行行列轉換了,先看11G之前,利用decode函式來實現行列轉換
再看看11G新特性pivot實現行列轉換,如下:
實際上,oracle對pivot子句中出現的列以外的列做了一個隱式的group by.現在,如果想要再結果中增加1列,顯示部門的薪水總合,可以這麼做
說明:
1)oracle對pivot子句中出現的列以外的列,也就是deptno和SAL_TOTAL做了隱式的group by.這裡用了分析函式,對於每個deptno,SAL_TOTAL是唯一的,所以group by的結果還是3行。
2)oracle會拼接列名 = for字句中別名+聚合函式別名,比如'P'+'_'+'SAL_TOTAL'
可以指定多個聚合函式,如統計薪水總合與人數總合,如下:
for子句可以指定多列,如想統計salesman和clerk員工,其mgr為7902和7698各自的人數,如下:
先來看看pivot的語法是
點選(此處)摺疊或開啟
- SELECT ....
- FROM <table-expr>
- PIVOT
- (
- aggregate-function(<column>)
- FOR <pivot-column> IN (<value1>, <value2>,..., <valuen>)
- ) AS <alias>
- WHERE .....
點選(此處)摺疊或開啟
-
SQL> select empno,ename,job,sal,deptno from emp order by deptno,job;
-
-
EMPNO ENAME JOB SAL DEPTNO
-
---------- ---------- --------- ---------- ----------
-
7934 MILLER CLERK 1300 10
-
7782 CLARK MANAGER 2450 10
-
7839 KING PRESIDENT 5000 10
-
7902 FORD ANALYST 3000 20
-
7369 SMITH CLERK 800 20
-
7566 JONES MANAGER 2975 20
-
7900 JAMES CLERK 950 30
-
7698 BLAKE MANAGER 2850 30
-
7844 TURNER SALESMAN 1500 30
-
7521 WARD SALESMAN 1250 30
-
7499 ALLEN SALESMAN 1600 30
-
-
EMPNO ENAME JOB SAL DEPTNO
-
---------- ---------- --------- ---------- ----------
-
7654 MARTIN SALESMAN 1250 30
-
- 已選擇12行。
點選(此處)摺疊或開啟
-
SQL> select deptno,job,sum(sal) from emp group by deptno,job order by 1,2;
-
-
DEPTNO JOB SUM(SAL)
-
---------- --------- ----------
-
10 CLERK 1300
-
10 MANAGER 2450
-
10 PRESIDENT 5000
-
20 ANALYST 3000
-
20 CLERK 800
-
20 MANAGER 2975
-
30 CLERK 950
-
30 MANAGER 2850
-
30 SALESMAN 5600
-
- 已選擇9行。
點選(此處)摺疊或開啟
-
SQL> edit
-
已寫入 file afiedt.buf
-
-
1 select deptno,
-
2 sum(decode(job,'CLERK',sal,0)) as CLERK_sal,
-
3 sum(decode(job,'MANAGER',sal,0)) as MANAGER_sal,
-
4 sum(decode(job,'PRESIDENT',sal,0)) as PRESIDENT_sal,
-
5 sum(decode(job,'ANALYST',sal,0)) as ANALYST_sal,
-
6 sum(decode(job,'SALESMAN',sal,0)) as SALESMAN_sal
-
7* from emp group by deptno order by 1
-
SQL> /
-
-
DEPTNO CLERK_SAL MANAGER_SAL PRESIDENT_SAL ANALYST_SAL SALESMAN_SAL
-
---------- ---------- ----------- ------------- ----------- ------------
-
10 1300 2450 5000 0 0
-
20 800 2975 0 3000 0
-
30 950 2850 0 0 5600
-
- SQL>
再看看11G新特性pivot實現行列轉換,如下:
點選(此處)摺疊或開啟
-
SQL> edit;
-
已寫入 file afiedt.buf
-
-
1 select * from(
-
2 select deptno,job,sal from emp
-
3 )
-
4 pivot(
-
5 sum(sal) for job in(
-
6 'PRESIDENT' as PRESIDENT_SAL,
-
7 'MANAGER' as MANAGER_SAL,
-
8 'ANALYST' as ANALYST_SAL,
-
9 'CLERK' as CLERK_SAL,
-
10 'SALESMAN' as SALESMAN_SAL
-
11 )
-
12* ) order by 1
-
SQL> /
-
-
DEPTNO PRESIDENT_SAL MANAGER_SAL ANALYST_SAL CLERK_SAL SALESMAN_SAL
-
---------- ------------- ----------- ----------- ---------- ------------
-
10 5000 2450 1300
-
20 2975 3000 800
-
30 2850 950 5600
-
- SQL>
實際上,oracle對pivot子句中出現的列以外的列做了一個隱式的group by.現在,如果想要再結果中增加1列,顯示部門的薪水總合,可以這麼做
點選(此處)摺疊或開啟
-
SQL> edit
-
已寫入 file afiedt.buf
-
-
1 select * from(
-
2 select deptno,job,sal,sum(sal) over(partition by deptno) sal_total from emp
-
3 )
-
4 pivot(
-
5 sum(sal) as total_sal for job in(
-
6 'PRESIDENT' as P,
-
7 'MANAGER' as M,
-
8 'ANALYST' as A,
-
9 'CLERK' as C,
-
10 'SALESMAN' as S
-
11 )
-
12* ) order by 1
-
SQL> /
-
-
DEPTNO SAL_TOTAL P_TOTAL_SAL M_TOTAL_SAL A_TOTAL_SAL C_TOTAL_SAL S_TOTAL_SAL
-
---------- ---------- ----------- ----------- ----------- ----------- -----------
-
10 8750 5000 2450 1300
-
20 6775 2975 3000 800
-
30 9400 2850 950 5600
-
- SQL>
1)oracle對pivot子句中出現的列以外的列,也就是deptno和SAL_TOTAL做了隱式的group by.這裡用了分析函式,對於每個deptno,SAL_TOTAL是唯一的,所以group by的結果還是3行。
2)oracle會拼接列名 = for字句中別名+聚合函式別名,比如'P'+'_'+'SAL_TOTAL'
可以指定多個聚合函式,如統計薪水總合與人數總合,如下:
點選(此處)摺疊或開啟
-
SQL> edit;
-
已寫入 file afiedt.buf
-
-
1 select * from(
-
2 select deptno,job,sal from emp
-
3 )
-
4 pivot(
-
5 sum(sal) as sal_total,count(sal) as emp_total for job in(
-
6 'PRESIDENT' as PRESIDENT,
-
7 'MANAGER' as MANAGER
-
8 )
-
9* ) order by 1
-
SQL> /
-
-
DEPTNO PRESIDENT_SAL_TOTAL PRESIDENT_EMP_TOTAL MANAGER_SAL_TOTAL MANAGER_EMP_TOTAL
-
---------- ------------------- ------------------- ----------------- -----------------
-
10 5000 1 2450 1
-
20 0 2975 1
- 30 0 2850 1
for子句可以指定多列,如想統計salesman和clerk員工,其mgr為7902和7698各自的人數,如下:
點選(此處)摺疊或開啟
-
SQL> edit;
-
已寫入 file afiedt.buf
-
-
1 select * from(
-
2 select deptno,job,mgr from emp
-
3 )
-
4 pivot(
-
5 count(mgr) as emp_total for(job,mgr) in(
-
6 ('SALESMAN', '7902') as SALESMAN_7902,
-
7 ('SALESMAN', '7698') as SALESMAN_7698,
-
8 ('CLERK', '7902') as CLERK_7902,
-
9 ('CLERK', '7698') as CLERK_7698
-
10 )
-
11* )
-
SQL> /
-
-
DEPTNO SALESMAN_7902_EMP_TOTAL SALESMAN_7698_EMP_TOTAL CLERK_7902_EMP_TOTAL CLERK_7698_EMP_TOTAL
-
-
---------- ----------------------- ----------------------- -------------------- --------------------
-
-
30 0 4 0 1
-
-
20 0 0 1 0
-
- 10 0 0 0 0
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21251711/viewspace-1734828/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spark實現行列轉換pivot和unpivotSpark
- oracle 11g 使用 pivot/unpivot 行列轉換Oracle
- SQL Server中行列轉換 Pivot UnPivotSQLServer
- SQL Server 2005之PIVOT/UNPIVOT行列轉換(轉)SQLServer
- Oracle行列轉換及pivot子句的用法Oracle
- oracle11g pivot 行列轉換 SQL Server 2005OracleSQLServer
- 用ORACLE分析函式實現行列轉換Oracle函式
- 試驗Oracle中實現行列轉換的方法(轉)Oracle
- sql的行轉列(PIVOT)與列轉行(UNPIVOT)SQL
- sql pivot、unpivot和partition by用法SQL
- Oracle--SQL行列轉換實戰OracleSQL
- Oracle-行列轉換Oracle
- sql 實現表的行列轉換SQL
- oracle行列轉換-行轉列Oracle
- oracle行列轉換-列轉行Oracle
- oracle行列轉換-多行轉換成字串Oracle字串
- Oracle 行列轉換 經典Oracle
- Oracle 行列轉換總結Oracle
- Oracle 行列轉換小結Oracle
- Oracle行列轉換總結Oracle
- WORD及EXCEL行列轉換實現方法收藏(轉)Excel
- oracle行列轉換-字串轉換成多列Oracle字串
- oracle行列轉換-多列轉換成字串Oracle字串
- SQL Server 實現行列(縱橫表)轉換SQLServer
- oracle和mysql的行列轉換OracleMySql
- 行列轉換
- 使用vue實現行列轉換的一種方法。Vue
- 在Word中實現表格的行列互換 (轉)
- Oracle 11g使用UNPIVOT函式實現“列轉行”Oracle函式
- Oracle 11g Pivot函式實現行轉列Oracle函式
- wmsys.wm_concat 實現行列轉換問題
- Kettle行列轉換
- 偽行列轉換!
- 行列轉換sqlSQL
- 用abap實現內表的行列轉換-原始碼2 (轉)原始碼
- 警示:通過 wmsys.wm_concat 實現行列轉換
- 行列轉換 交叉表 (轉)
- MySQL行列轉換拼接MySql