oracle的Rollup/cube/grouping sets

        如果是Group by ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。
  如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。        grouping_id()可以美化效果。除了使用GROUPING函数,还可以使用GROUPING_ID来标识GROUP BY的结果。

 也可以 Group by Rollup(A,(B,C)) ,Group by ARollup(B,C),…… 这样任意按自己想要的形式结合统计数据;

1、grouping()函数 

  必须接受一列且只能接受一列做为其参数。参数列值为空返回1,参数列值非空返回0。 

2、grouping_id()函数 

  必须接受一列或多列做为其参数。 

3.group by grouping sets(A,B)只对单列进行分组;

例1:rollup

 

--求各部门的各职位的工资,并按照job汇总,并添加总汇总

select e.deptno,e.job,sum(e.sal) job_sal  from emp e

group by e.deptno,e.job

order by e.deptno;

 

--如何汇总呢

--方式1: union all

select *

  from (select e.deptno, e.job, sum(e.sal) job_sal

          from emp e

         group by e.deptno, e.job

        union all

        select e.deptno, null, sum(e.sal)

          from emp e

         group by e.deptno

        union all

        select  null, null,sum(e.sal) from emp e) tt

 order by tt.deptno,tt.job;

 

--这种方式,emp会被访问3次

 

--方式2:  rollup

--只访问一次emp,效果跟上面的一模一样,具体你可以看执行计划

--

--先看单个分组,就是先根据deptno分组,最后再汇总

select e.deptno,sum(e.sal) from emp e

group by rollup(e.deptno);

 

--再看多个分组    先根据  e.deptno,e.job分组,再根据deptno分组,再全局统计,维度随便加

select e.deptno,e.job,sum(e.sal) from emp e

group by rollup(e.deptno,e.job);

 

 

--标记

select grouping(e.deptno) 列标记1,

       grouping(e.job) 列标记2,

       grouping_id(e.deptno, e.job) 结果标记,

       e.deptno,

       e.job,

       sum(e.sal)

  from emp e

 group by rollup(e.deptno, e.job);


例2:Cube的维度更小:

 

select grouping(e.deptno) 列标记1,

       grouping(e.job) 列标记2,

       grouping_id(e.deptno, e.job) 结果标记,

       e.deptno,

       e.job,

       sum(e.sal)

  from emp e

 group by cube(e.deptno, e.job);

例3:group by groupingsets

select null,e.job,sum(e.sal) from emp e

group by e.job

union all

select e.deptno,null,sum(e.sal) from emp e

group by e.deptno;

 

--等价于

select e.deptno,e.job,sum(e.sal) from emp e

group by grouping sets(e.deptno,e.job);


参考:https://www.2cto.com/database/201204/127014.html

猜你喜欢

转载自blog.csdn.net/u011165335/article/details/80246243