之前寫過一篇行轉列的文章:Oracle 簡單的列轉行
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production
需求是,統計每個部門不同工種的薪水總和。
SQL> select deptno,ename,job,sal from emp; DEPTNO ENAME JOB SAL ---------- ---------- --------- ---------- 20 SMITH CLERK 800 30 ALLEN SALESMAN 1600 30 WARD SALESMAN 1250 20 JONES MANAGER 2975 30 MARTIN SALESMAN 1250 30 BLAKE MANAGER 2850 10 CLARK MANAGER 2450 20 SCOTT ANALYST 3000 10 KING PRESIDENT 5000 30 TURNER SALESMAN 1500 20 ADAMS CLERK 1100 30 JAMES CLERK 950 20 FORD ANALYST 3000 10 MILLER CLERK 1300
已選擇14行。
SQL> select deptno, nvl(sum(decode(job, 'MANAGER', sal)), 0) "s_MANAGER", nvl(sum(decode(job, 'ANALYST', sal)), 0) "s_ANALYST", nvl(sum(decode(job, 'CLERK', sal)), 0) "s_CLERK", nvl(sum(decode(job, 'PRESIDENT', sal)), 0) "s_PRESIDENT", nvl(sum(decode(job, 'SALESMAN', sal)), 0) "s_SALESMAN" from emp group by deptno; DEPTNO s_MANAGER s_ANALYST s_CLERK s_PRESIDENT s_SALESMAN ---------- ---------- ---------- ---------- ----------- ---------- 30 2850 0 950 0 5600 20 2975 6000 1900 0 0 10 2450 0 1300 5000 0
用pivot會更簡潔
SQL> with p as (select deptno,job,sal from emp) SELECT * FROM p pivot ( SUM(sal) FOR job IN ('MANAGER' as "s_MANAGER", 'ANALYST' as "s_ANALYST", 'CLERK' as "s_CLERK", 'PRESIDENT' as "s_PRESIDENT", 'SALESMAN' as "s_SALESMAN" )); DEPTNO s_MANAGER s_ANALYST s_CLERK s_PRESIDENT s_SALESMAN ---------- ---------- ---------- ---------- ----------- ---------- 30 2850 950 5600 20 2975 6000 1900 10 2450 1300 5000