Oracle 简单的列转行

    需求是,统计每一个部门不同工种的薪水总和。

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


SQL> select deptno,
           nvl(sum(case job when 'MANAGER' then sal else null end), 0) "s_MANAGER",
           nvl(sum(case job when 'ANALYST' then sal else null end), 0) "s_ANALYST",
           nvl(sum(case job when 'CLERK' then sal else null end), 0) "s_CLERK",
           nvl(sum(case job when 'PRESIDENT' then sal else null end), 0) "s_PRESIDENT",
           nvl(sum(case job when 'SALESMAN' then sal else null end), 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


    需求是查询每一个部门下的人员信息,在一行显示。在oracle 10g和11g上能够用WMSYS.WM_CONCAT,但值得注意的是此函数是undocument的函数(不是官方发布的函数),oracle不保证升级之后还会存在。

SQL> SELECT deptno, WMSYS.WM_CONCAT(ename) AS employees FROM emp GROUPBY deptno;

    DEPTNO EMPLOYEES

---------- --------------------------------------

        10 CLARK,MILLER,KING

        20 SMITH,FORD,ADAMS,SCOTT,JONES

        30ALLEN,JAMES,TURNER,BLAKE,MARTIN,WARD

    Oracle 11g后,能够用listagg实现。

SQL> SELECT deptno, LISTAGG(ename, ',') WITHIN

     GROUP( ORDER BY ename) AS employees

      FROM emp

     GROUP BY deptno;

    DEPTNO EMPLOYEES

---------- ---------------------------------------

        10 CLARK,KING,MILLER

        20ADAMS,FORD,JONES,SCOTT,SMITH

        30ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD


原文地址:https://www.cnblogs.com/gavanwanggw/p/7137575.html