前面介绍了分组函数的基本用法,下面介绍几种关于GROUP BY更高级的用法。
1、ORACLE数据库中的ROLLUP配合GROUP BY命令使用,可以提供信息汇总功能(与"小计"相似)
SQL> SELECT deptno, job,sum(sal) from emp1 group by deptno,job
2 order by deptno,job;
DEPTNO JOB SUM(SAL)
---------- --------------------------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
40 SALESMAN 6000
//会对每一个不同的dept,job生成一行独立的结果
1 SELECT deptno, job,sum(sal) from emp1
2 group by rollup(deptno,job)
3* order by deptno,job
SQL> /
DEPTNO JOB SUM(SAL)
---------- --------------------------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
20 10875
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
30 9400
40 SALESMAN 6000
40 6000
35025
//结果中除了上述的结果结果之外,还会对每一个deptno进行一个小结,并单独生成一行,除此之外还会对所有的sal求和并生成一行。
总结:
(1)可以看出,用了rollup的group by子句所产生的所谓的超级聚合就是指在在产生聚合时会从右向左逐个对每一列进行小结,并在结果中生成独立的一行,同时也会对聚合列生成一个合计列。
(2)这里的group by后面我们仅仅接了2列,实际上我们可以使用更多列的,这样的话oracle就会以从右向左的方式来进行逐个小结。
2、CUBE,也是GROUP BY子句的一种扩展
可以返回每一个列组合的小计记录(从左向右+从右向左),同时在末尾加上总计记录。
1 SELECT deptno, job,sum(sal) from emp1
2 group by cube(deptno,job)
3* order by deptno,job
SQL> /
DEPTNO JOB SUM(SAL)
---------- --------------------------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
20 10875
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
30 9400
40 SALESMAN 6000
40 6000
ANALYST 6000
CLERK 4150
MANAGER 8275
PRESIDENT 5000
SALESMAN 11600
35025
这里需要注意的是是使用了group by和rollup后,其后面的列要用括号括起来,否则将会出现ORA-00933: SQL 命令未正确结束的错误。
3、其他情况
但是我们大多数情况下需要在查询的结果集的汇总列加上“合计”,怎么办呢?用grouping和grouping_id函数,然后再用decode函数判断一下是否为空就可以了。
select decode(grouping_id(job,deptno),1,'sum',job||deptno) as group_col,sum(sal) total_sal
from emp
group by rollup(job,deptno);
GROUP_COL TOTAL_SAL
------------------ ----------
CLERK10 1300
CLERK20 1900
CLERK30 950
sum 4150
ANALYST20 6000
sum 6000
MANAGER10 2450
MANAGER20 2975
MANAGER30 2850
sum 8275
SALESMAN30 5600
sum 5600
PRESIDENT10 5000
sum 5000
29025
GROUPING函数可以接受一列,返回0或者1。如果列值为空,那么GROUPING()返回1;如果列值非空,那么返回0。GROUPING只能在使用ROLLUP或CUBE的查询中使用。当需要在返回空值的地方显示某个值时,GROUPING()就非常有用。
总机:(010)-56426307,59426319 QQ讨论群:243729577 182441349 邮箱:yuezt@cuug.com
通信地址:北京市海淀区紫竹院路88号紫竹花园D座703(CUUG)邮政编码:100089
中国UNIX用户协会 Copyright 2010 ALL Rights Reserved 北京神脑资讯技术有限公司
京ICP备11008061号