生成报表数据时,经常会加上一行合计,大多时候会用UNION ALL来实现,虽然也能达到目的,但是用UNION ALL往往效率会比较低,Oracle提供了计算合计的函数ROLLUP
SELECT decode(t.deptno,NULL,'合计',t.deptno) AS deptno,
SUM(sal) AS sal
FROM scott.emp t
GROUP BY ROLLUP(t.deptno);
上述语句中,ROLLUP是GROUP BY 子句的扩展,可以为每个分组返回小计记录,以及为所有的分组返回总机记录。
可以以两个字段分组(注意rollup后是两对括号)
SELECT decode(t.deptno,NULL,'总计',t.deptno) deptno,
t.job,
SUM(sal) AS sal
FROM scott.emp t
GROUP BY ROLLUP((t.deptno,t.job));
还可以统计组内小计
SELECT decode(t.deptno,NULL,'总计',t.deptno) deptno,
decode(t.deptno,NULL,null,decode(t.job,NULL,'小计',t.job)) job,
COUNT(*)
FROM scott.emp t
GROUP BY ROLLUP(t.deptno,t.job)
也可以换种写法,Oracle提供了grouping函数,具体如下
SELECT decode(grouping(t.deptno),1,'总计',t.deptno) deptno,
grouping(t.deptno),
decode(grouping(t.deptno),1,null,decode(grouping(t.job),1,'小计',t.job)) job,
grouping(t.job),
COUNT(*)
FROM scott.emp t
GROUP BY ROLLUP(t.deptno,t.job)
grouping得出的结果为0时,表示此行数据是以grouping后的属性分组的,所以
当grouping(depton)和grouping(job)都为0时,表示此行数据是以depton和job为分组依据统计出来的结果
当grouping(depton)为0 grouping(job)为1时,表示此行数据是以depton为分组依据统计出来的结果
当grouping(depton)和 grouping(job)都为1时,表示此行数据是合计的结果