oracle9i學習筆記之十五 增強GROUP BY子句

 1.組及組函數回顧

  SELECT    [column,]group_function(column)...
  FROM      table
  [WHERE    condition]
  [GROUP BY group_by_expression]
  [ORDER BY column];

例1:計算工作崗位以CL開頭的各部門僱員的平均薪水、有佣金收入的僱員數和最晚受僱日期
   
    SELECT  AVG(sal),COUNT(comm),MAX(hiredate)
    FROM    emp
    WHERE   job LIKE 'CL%';

   
例2:查詢emp表,按照部門編號和工作崗位分組,顯示部門編號、工作崗位、薪水合計、有佣金收入的僱員數
    SELECT   deptno,job,SUM(sal),COUNT(comm)
    FROM     emp
    GROUP BY deptno,job;


2.HAVING子句的回顧
 
  SELECT    [column,]group_function(column)...
  FROM      table
  [WHERE    condition]
  [GROUP BY group_by_expression]
  [HAVING   having_expression]
  [ORDER BY column] ;
 
例:查詢emp表,按照部門編號進行分組,顯示平均薪水高於$2000的部門編號和平均薪水

    SELECT   deptno,AVG(sal)
    FROM     emp
    GROUP BY deptno
    HAVING   AVG(sal)>2000;

3.ROLLUP操作

  SELECT    [column,]group_function(column)...
  FROM      table
  [WHERE    condition]
  [GROUP BY [ROLLUP]group_by_expression]
  [HAVING   having_expression]
  [ORDER BY column] ;

1)ROLLUP分組產生一個包含常規分組行和小計值的結果集
2)ROLLUP是一個GROUP BY 子句的擴展
3)用ROLLUP操作產生小計和累計
 
例:
   SELECT   deptno department_id,job job_id,SUM(sal) salary
   FROM     emp
   WHERE    deptno<60
   GROUP BY ROLLUP(deptno,job);
結果:
        DEPARTMENT_ID  JOB_ID     SALARY 
             10                   3000 
             10        CLERK      1300 
             10        MANAGER    2450 
             10        PRESIDENT  5000 
             10                   11750  //dept10薪水小計
             20        CLERK      3100 
             20        ANALYST    6000 
             20        MANAGER    2975 
             20                   12075  //dept20薪水小計 
             30        CLERK      950 
             30        MANAGER    2850 
             30        SALESMAN   5600 
             30                   9400  //dept30薪水小計
                                  33225 //所有salary之和


4.CUBE操作

  SELECT    [column,]group_function(column)...
  FROM      table
  [WHERE    condition]
  [GROUP BY [CUBE]group_by_expression]
  [HAVING   having_expression]
  [ORDER BY column] ;

1)CUBE是GROUP BY子句的擴展
2)CUBE分組是產生一個包含ROLLUP行和交叉錶行的結果集
 
例:
    SELECT    deptno department_id,job job_id,SUM(sal) salary
    FROM      emp
    WHERE     deptno<60
    GROUP BY  CUBE(deptno,job)
    ORDER BY  1;
結果:
        DEPARTMENT_ID  JOB_ID    SALARY 
             10        CLERK     1300 
             10        MANAGER   2450 
             10        PRESIDENT 5000 
             10                  3000 
             10                  11750 
             20        ANALYST   6000 
             20        CLERK     3100 
             20        MANAGER   2975 
             20                  12075 
             30        CLERK     950 
             30        MANAGER   2850 
             30        SALESMAN  5600 
             30                  9400 
                       ANALYST   6000 
                       CLERK     5350 
                       MANAGER   8275 
                       PRESIDENT 5000 
                       SALESMAN  5600 
                                 3000 
                                 33225 

5.GROUPING函數

  SELECT    [column,]group_function(column),GROUPING(expr)
  FROM      table
  [WHERE    condition]
  [GROUP BY [ROLLUP][CUBE]group_by_expression]
  [HAVING   having_expression]
  [ORDER BY column] ;

1)GROUPING函數既可以用於CUBE操作,也可以用於ROLLUP操作
2)用GROUPING函數模擬能夠發現在一行中的構成小計的分組
3)GROUPING函數返回0或1
 
例:
   SELECT   deptno deptid,job,SUM(sal),
            GROUPING(deptno) GRP_DEPT,
            GROUPING(job) GRP_JOB
   FROM     emp
   WHERE    deptno<50
   GROUP BY ROLLUP(deptno,job);

結果:
     DEPTID  JOB    SUM(SAL)  GRP_DEPT  GRP_JOB 
       10             3000       0         0 
       10   CLERK     1300       0         0 
       10   MANAGER   2450       0         0 
       10   PRESIDENT 5000       0         0 
       10             11750      0         1 
       20   CLERK     3100       0         0 
       20   ANALYST   6000       0         0 
       20   MANAGER   2975       0         0 
       20             12075      0         1 
       30   CLERK     950        0         0 
       30   MANAGER   2850       0         0 
       30   SALESMAN  5600       0         0 
       30             9400       0         1 
                      33225      1         1 

已選擇14行。

6.分組集
1)GROUPING SETS是GROUP BY子句更進一步的擴展
2)能夠用GROUPING SETS在同一查詢中定義多個分組
3)Oracle服務器計算在GROUPING SETS子句中指定的所有分組
4)分組集合的效率:
  -對基表僅進行一次查詢
  -不需要寫複雜的UNION語句
  -GROUPING SETS有更多的元素,更好的執行性能 

例:
    SELECT    deptno department_id,job job_id,
              mgr manager_id,AVG(sal) salary
    FROM      emp
    GROUP BY  GROUPING SETS((deptno,job),(job,mgr));
結果:
      DEPARTMENT_ID  JOB_ID  MANAGER_ID  SALARY 
          10                              3000 
          10         CLERK                1300 
          10         MANAGER              2450 
          10         PRESIDENT            5000 
          20         CLERK                1550 
          20         ANALYST              3000 
          20         MANAGER              2975 
          30         CLERK                950 
          30         MANAGER              2850 
          30         SALESMAN             1400 
                                          3000 
                     CLERK      7698      950 
                     CLERK      7782      1300 
                     CLERK      7788      1100   
                     CLERK      7902      2000 
                     ANALYST    7566      3000 
                     MANAGER    7839      2758.33333 
                     SALESMAN   7698      1400 
                     PRESIDENT            5000 

已選擇19行。


7.複合列
1)複合列是一個作爲整體被處理的列集合
  -ROLLUP(a,(b,c),d)
2)爲了指定複合列,用GROUP BY子句來分組在圓括號內的列,因此Oracle服務器在進行ROLLUP
或CUBE操作時將它們作爲一個整體來處理
3)當使用ROLLUP或CUBE時,複合列將跳過在確定級別上的聚合

例:
   SELECT   deptno,job,mgr,SUM(sal)
   FROM     emp
   GROUP BY ROLLUP(deptno,(job,mgr));
結果:
      DEPTNO  JOB     MGR    SUM(SAL) 
        10                    3000 
        10   CLERK    7782    1300 
        10   MANAGER  7839    2450 
        10   PRESIDENT        5000 
        10                    11750 
        20   CLERK    7788    1100 
        20   CLERK    7902    2000 
        20   ANALYST  7566    6000 
        20   MANAGER  7839    2975 
        20                    12075 
        30   CLERK    7698    950 
        30   MANAGER  7839    2850 
        30   SALESMAN 7698    5600 
        30                    9400 
                              33225 


練習
1.查詢emp表,根據部門編號、工作崗位、所屬的經理編號進行分組,使用ROLLUP查詢薪水的合計

   SELECT   deptno,job,mgr,SUM(sal)
   FROM     emp
   GROUP BY ROLLUP(deptno,job,mgr);

2.查詢emp表,根據部門編號、工作崗位、所屬的經理編號進行分組,使用CUBE查詢薪水的合計

   SELECT   deptno,job,mgr,SUM(sal)
   FROM     emp
   GROUP BY CUBE(deptno,job,mgr);

3.用GROUPING SETS寫一個查詢,顯示下面的分組:
    deptno,mgr,job
    deptno,job
    mgr,job
  查詢計算每個分組的工資總數

   SELECT   deptno,job,mgr,SUM(sal)
   FROM     emp
   GROUP BY GROUPING SETS((deptno,job,mgr),(deptno,job),(mgr,job));

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章