您好!欢迎访问家园网-www.jy.wang!

家园网

下面代码为Oracle数据库使用ROLLUP关键字统计Oracle数据库自带的emp员工表中每个部门的工资总和,请讲解一下

网络 作者:本站 点击:

下面代码为Oracle数据库使用ROLLUP关键字统计

Oracle数据库自带的emp员工表中每个部门的工资总和,请讲解一下

SELECT e.deptno, d.dname, SUM(e.sal) AS 工资总和
FROM emp e,dept d
WHERE e.deptno = d.deptno
GROUP BY ROLLUP(e.deptno, d.dname);

Oracle ROLLUP 关键字统计工资总和详解

让我详细讲解这段代码,特别是 ROLLUP 的作用。


一、代码整体功能

这段代码的作用是:按部门统计员工工资总和,并同时生成所有部门的合计行

sql

SELECT e.deptno, d.dname, SUM(e.sal) AS 工资总和FROM emp e, dept dWHERE e.deptno = d.deptnoGROUP BY ROLLUP(e.deptno, d.dname);


二、ROLLUP 是什么?

词源角度

单词词源含义
ROLLUProll(滚动)+ up(向上)向上汇总、逐级累计

字面意思:把数据"向上滚动"汇总,从细粒度到粗粒度逐级聚合。


三、ROLLUP 的作用

ROLLUP 是 Oracle 中的分组扩展语法,它在正常分组的基础上,额外生成小计和总计行

GROUP BY ROLLUP(A, B) 产生的分组组合

分组级别分组依据说明
第1组(A, B)正常分组(最细粒度)
第2组(A)A 的小计
第3组()总计

四、假设数据

emp 表(员工表)

empno

ename

sal

deptno

1001

张三

5000

10

1002

李四

6000

10

1003

王五

7000

20

1004

赵六

8000

20

1005

孙七

9000

30


dept 表(部门表)

deptnodname
10财务部
20技术部
30销售部

五、不同写法的结果对比

写法1:普通 GROUP BY(无 ROLLUP)

sql

SELECT e.deptno, d.dname, SUM(e.sal) AS 工资总和FROM emp e, dept dWHERE e.deptno = d.deptnoGROUP BY e.deptno, d.dname;

结果

deptnodname工资总和
10财务部11000
20技术部15000
30销售部9000

只有 3 行(每个部门一行)。


写法2:使用 ROLLUP

sql

SELECT e.deptno, d.dname, SUM(e.sal) AS 工资总和FROM emp e, dept dWHERE e.deptno = d.deptnoGROUP BY ROLLUP(e.deptno, d.dname);

结果

deptno

dname

工资总和

说明

10

财务部

11000

部门10的工资总和

20

技术部

15000

部门20的工资总和

30

销售部

9000

部门30的工资总和

10

(null)

11000

部门10的小计(重复?等等,让我重新计算)


实际上,ROLLUP(e.deptno, d.dname) 会按以下顺序分组:


六、ROLLUP(e.deptno, d.dname) 产生的分组

text

┌─────────────────────────────────────────────────────────────┐
│ 第1级分组:按 (deptno, dname) 分组                          │
│ 结果:每个部门一行                                           │
├─────────────────────────────────────────────────────────────┤
│ 第2级分组:按 (deptno) 分组                                 │
│ 结果:每个部门一行(dname 为 NULL)                         │
│ 注意:这里与第1级结果重复?不对,让我仔细分析                 │
└─────────────────────────────────────────────────────────────┘

实际上,ROLLUP 会生成 N+1 种分组组合(N = 列数)。

对于 ROLLUP(A, B)

分组级别分组列说明
1(A, B)正常分组
2(A)按 A 分组的小计
3()总计

七、实际执行结果

deptno

dname

工资总和

分组级别

10

财务部

11000

(10, 财务部)

20

技术部

15000

(20, 技术部)

30

销售部

9000

(30, 销售部)

10

(null)

11000

(10) 部门10小计

20

(null)

15000

(20) 部门20小计

30

(null)

9000

(30) 部门30小计

(null)

(null)

35000

() 总计



问题:这里部门小计和部门明细是重复的?不,它们的语义不同:

  • 第1-3行:(10,财务部) 是该部门下按 dname 分组(实际上 dname 是唯一的,所以相同)

  • 第4-6行:(10,null) 是只按 deptno 分组的小计(当有多个部门名时才有意义)


八、更清晰的示例

为了看清 ROLLUP 的效果,假设 dname 有不同的值:

如果 ROLLUP(e.deptno, e.job)(按部门和职位统计):

deptno

job

SUM(sal)

说明

10

经理

5000

部门10经理

10

职员

6000

部门10职员

20

经理

7000

部门20经理

20

职员

8000

部门20职员

10

(null)

11000

部门10小计

20

(null)

15000

部门20小计

(null)

(null)

26000

总计


这样就能清楚看到 ROLLUP 的作用:逐级向上汇总


九、ROLLUP 的可视化理解

text

原始数据(员工工资)
         ↓
按 (deptno, dname) 分组 → 每个部门一行
         ↓
        ROLLUP 向上滚动
         ↓
按 (deptno) 分组 → 每个部门的小计(如果 dname 有多个,这里会有意义)
         ↓
        ROLLUP 继续向上滚动
         ↓
按 () 分组 → 总计


十、ROLLUP vs CUBE vs GROUPING SETS

语法作用分组组合数
ROLLUP(A, B)逐级向上汇总N+1 = 3
CUBE(A, B)所有组合2^N = 4
GROUPING SETS((A), (B))指定组合自定义

十一、总结

问题答案
ROLLUP 是什么?分组扩展,生成逐级小计和总计
ROLLUP(e.deptno, d.dname) 产生哪些分组?1. (deptno, dname)
2. (deptno)
3. ()
结果行数正常分组数 + 小计行数 + 1(总计)
词源roll(滚动)+ up(向上)= 向上汇总
与普通 GROUP BY 的区别普通 GROUP BY 只有明细,ROLLUP 增加小计和总计

一句话总结ROLLUP 就像逐级向上汇总——先从最细粒度(部门+部门名)统计,然后"向上滚动"到部门级别统计小计,最后滚动到最顶层统计总计。ROLLUP(e.deptno, d.dname) 会生成 3 种分组:(deptno, dname) 的明细、(deptno) 的部门小计、() 的总计,最终结果行数 = 正常分组数 + 分组层级数


标签: