概述
今天主要分享下Oracle数据库分组函数group by 、 rollup、cude、grouping 、grouping sets的常用用法,以下以Oracle自带schema做演示。
1、group by的使用
--根据DEPTNO和JOB进行分组。求相同DEPTNO,相同JOB的员工工资总和。
SELECT E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY E.DEPTNO,E.JOB ORDER BY E.DEPTNO;
![173cd04b0e82c19c84597c54307be103.png](https://i-blog.csdnimg.cn/blog_migrate/394d3c2c7ba8f6b7bf3b565d190e6bee.jpeg)
2、group by 配合rollup的使用
rollup()--可以使用一个或者多个参数。意思是从右向左进行数据的汇总统计,并生成一行,rollup是个统计函数。
以下是根据分组情况进行统计,最终进行全部汇总。
(1)简单的使用rollup--生成一行新数据。(要生成新的一行数据,还可以使用UNION ALL)
SELECT D.DUMMY FROM DUAL D GROUP BY ROLLUP(D.DUMMY);
![d65aa36a80cfdfaf65e08a22b9fdcd85.png](https://i-blog.csdnimg.cn/blog_migrate/1e0fcbf30eb5d8aae6a7f29e0065a898.jpeg)
(2)先根据E.DEPTNO,E.JOB进行分组,然后从右向左
SELECT E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY ROLLUP(E.DEPTNO,E.JOB) ORDER BY E.DEPTNO;
![bed0e22d3074a12449ac8affa3c756fa.png](https://i-blog.csdnimg.cn/blog_migrate/e801196a4b954ea6473bd172d821e932.jpeg)
针对以上的使用ROLLUP的结果的理解:
a:首先根据GROUP BY E.DEPTNO,E.JOB查询出9条数据(除4,8,12,13外),在根据rollup的定义,从右向左,对ROLLUP中的参数进行小计
首先根据JOB(对所有的JOB进行汇总),汇总出4,8,12行,在根据E.DEPTNO(对所有的DEPTNO进行汇总),汇总出第十三行数据。
(3) 特殊情况
SELECT E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY ROLLUP(E.JOB,E.DEPTNO) ORDER BY E.DEPTNO;
![205f2cee6b372c35ea3e9f346e8fed8e.png](https://i-blog.csdnimg.cn/blog_migrate/5c940d91ddefb9f79b7a485f0d784211.jpeg)
理解:首先根据GROUP BY E.DEPTNO,E.JOB查询出前九条数据,其次对E.DEPTNO进行汇总,但是必须考虑JOB,也就是相同的JOB,的所有的工资总和,所以出现下面五条数据。
3、group by 配合cube的使用
SELECT E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY CUBE(E.DEPTNO,E.JOB) ORDER BY E.DEPTNO;
![6a964bc04c613346420798bf876a30a6.png](https://i-blog.csdnimg.cn/blog_migrate/8094442a7852495d8d5f5ebf477663de.jpeg)
理解:CUBE会对条件中的每一个条件进行单独的汇总:即对单独的列进行汇总
GROUP BY CUBE(E.DEPTNO,E.JOB)首先根据:GROUP BY E.DEPTNO,E.JOB查询数据,其次对E.JOB进行汇总(不考虑DEPTNO,单独汇总,而ROLLUP是在同一个DEPTNO下面)再对E.DEPTNO进行汇总,最后全部汇总。
cube(a,b) 统计列包含:(a,b)、(a)、(b)、()cube(a,b,c) 统计列包含:(a,b,c)、(a,b)、(a,c)、(b,c)、(a)、(b)、(c)、()
4、GROUPING 的使用
GROUPING函数可以接受一列,返回0或者1。如果列值为空,那么GROUPING()返回1;如果列值非空,那么返回0。GROUPING只能在使用ROLLUP或CUBE的查询中使用。当需要在返回空值的地方显示某个值时,GROUPING()就非常有用。
SELECT GROUPING(E.DEPTNO), E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY ROLLUP(E.DEPTNO,E.JOB) ORDER BY E.DEPTNO;
![a17985f3843cdb7e7a47b6d2649cc7a3.png](https://i-blog.csdnimg.cn/blog_migrate/69d4abb858cf138556fd92b9a6a7eb52.jpeg)
可以使用decode或者case函数进行转换这种不友好的显示:
SELECT CASE WHEN grouping(E.DEPTNO) = 1THEN '总计'ELSE E.DEPTNO || ''END AS 部门,CASE WHEN grouping(E.JOB) = 1 AND grouping(E.DEPTNO) = 0THEN '小计'ELSE E.JOBEND AS 工作种类,SUM(E.SAL) FROM EMP E GROUP BY ROLLUP(E.DEPTNO,E.JOB)ORDER BY E.DEPTNO;
![4b02ea695a20130bee07d07984b10c6b.png](https://i-blog.csdnimg.cn/blog_migrate/e089fc08a054e6273e84c055c9ef4678.jpeg)
SELECT DECODE(GROUPING(E.DEPTNO), 1, '总计', E.DEPTNO) AS 部门,CASEWHEN GROUPING(E.JOB) = 1 AND GROUPING(E.DEPTNO) = 0 THEN'小计'ELSEE.JOBEND AS 工作种类,SUM(E.SAL)FROM EMP EGROUP BY ROLLUP(E.DEPTNO, E.JOB)ORDER BY E.DEPTNO;
![6e593606592618658ec4307c0b08fd02.png](https://i-blog.csdnimg.cn/blog_migrate/b800795c0dba66d6ed80a63c36da451f.jpeg)
5、grouping sets提供了指定汇总集合条件的功能
根据E.DEPTNO,E.JOB分别汇总数据。
SELECT E.DEPTNO,E.JOB,SUM(E.SAL) FROM EMP E GROUP BY GROUPING SETS(E.DEPTNO,E.JOB);
![bf97561e386a7e60d88777375c563a84.png](https://i-blog.csdnimg.cn/blog_migrate/968a7094ffc8a06c7549f4c66ac69a96.jpeg)
觉得有用的朋友多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~
![3d9807e327258a99475fe878c5dfe6b4.gif](https://i-blog.csdnimg.cn/blog_migrate/108c481463767650ccc9b2fba33467da.gif)