GROUP分组函数之ROLLUP

   /******************
  *ROLLUP函数的使用
  ******************/
 案例1
 需求:
 × 统计每个部门每个职位的薪水和
 × 统计每个部门所有职位的薪水小计
 × 统计所有部门所有职位的薪水合计
 × 需要显示部门名、职位名和累加后的薪水

--需求1
 SELECT D.DNAME, E.JOB, SUM(E.SAL) SUM_SAL
   FROM DEPT D, EMP E
  WHERE D.DEPTNO = E.DEPTNO
  GROUP BY D.DNAME, E.JOB
 UNION ALL
 --需求2
 SELECT D.DNAME, NULL, SUM(E.SAL) SUM_SAL
   FROM DEPT D, EMP E
  WHERE D.DEPTNO = E.DEPTNO
  GROUP BY D.DNAME
 UNION ALL
 --需求3
 SELECT NULL, NULL, SUM(E.SAL) SUM_SAL
   FROM DEPT D, EMP E
  WHERE D.DEPTNO = E.DEPTNO;
  


    


   

 --使用ROLLUP分组
 SELECT D.DNAME, E.JOB, SUM(E.SAL) AS SUM_SAL
   FROM DEPT D, EMP E
  WHERE D.DEPTNO = E.DEPTNO
  GROUP BY ROLLUP(D.DNAME, E.JOB);

    


    

   
ROLLUP(D.DNAME, E.JOB)的分组过程是:
 1)标准分组:GROUP BY (D.DNAME, E.JOB),对每个部门每个职位进行分组
 2)从右到左递减:GROUP BY (D.DNAME, NULL),其实这个NULL没有必要使用,这里只是为了
    方便分析。这个过程是对上一个级别分组的小计,也就是对每个DNAME值,计算横跨所有
    JOB的小计。
 3)最后合计:相当于 GROUP BY (NULL,NULL).
 
 上面的ROLLUP只用了两个列,如果有N个列,那么结果就是n+1中group by的组合,
 从右到左递减的过程中,下一个分组就是对上一个分组的小计。
 另外,在ROLLUP操作是,如果使用HINT:expand_gset_to_union,则优化器会将ROLLUP转为
 对应的UNION ALL操作。
 
案例2
 需求
 × 计算每个入职时间(年)、部门、职位的标准分组的薪水和;
 × 计算每个入职时间(年)、部门的所有职位的薪水小计;
 × 计算每个入职时间(年)的所有部门所有职位的薪水小计。
 × 最后合计薪水,显示入职时间(年)、部门名、职位名
 
 SELECT TO_CHAR(E.HIREDATE, ' yyyy') HIRE_YEAR,
        D.DNAME,
        E.JOB,
        SUM(SAL) SUM_SAL
   FROM DEPT D, EMP E
  WHERE D.DEPTNO = E.DEPTNO
  GROUP BY ROLLUP(TO_CHAR(E.HIREDATE, ' yyyy'), D.DNAME, E.JOB)
 

  

猜你喜欢

转载自anduo.iteye.com/blog/1679444