虽然已是AI的年代,但掌握AI的前提还的是自己掌握技能。更新一篇SQL函数,几个很好用却很少出现在SQL教程的内容。
你有没有遇到过这种情况:
领导说:"把这个月销售数据按部门跑一遍,再按城市跑一遍,最后按部门+城市再跑一遍,还有合计数据,也给我。"你默默打开了4个SQL文件,复制、粘贴、修改GROUP BY、运行、复制结果、粘贴到表格……一套下来,半小时没了。今天教你一个函数,1行SQL,搞定所有。
一、ROLLUP:自动帮你做层级汇总
场景是这样的:你的销售表有年度、月份、销售额三个字段。领导要:
按月汇总
按年度汇总
总计
传统写法怎么写?
SELECT month,SUM(amount) AS amountFROM salesGROUP BY month;SELECT year,SUM(amount) AS amountFROMsalesGROUP BY year;SELECT SUM(amount) AS amountFROM sales;
3个SQL,复制粘贴3次。
用 ROLLUP 怎么写?
SELECT year,month,SUM(amount) AS amountFROM salesGROUP BY ROLLUP(year,month);
1行,搞定3种汇总。
输出自动长这样:
year | month | SUM(amount) |
|---|
2024 | 1月 | 10000 |
2024 | 2月 | 15000 |
2024 | NULL | 25000 ← 按年度小计 |
2025 | 1月 | 12000 |
2025 | NULL | 12000 ← 按年度小计 |
NULL | NULL | 37000 ← 总计 |
等等,为什么有NULL?
这就是 ROLLUP 的聪明之处:它自动帮你生成"上级汇总"。
month是NULL的时候,就是年度小计;
两个都是NULL的时候,就是总计。
一句话解释:ROLLUP会按照参数从右到左,自动生成层级汇总。小计、总计,它帮你算好了。
二、CUBE:全排列组合汇总
如果说 ROLLUP 是"层层上卷",那 CUBE 就是"全排列"。
适用场景:领导要的是所有可能的组合。
比如:按部门看、按城市看、按部门+城市看、全部总计——4种组合全要。
SELECT dept,city,SUM(amount) AS amountFROM salesGROUP BY CUBE(dept,city);
输出包括:
4种组合,1行SQL。
什么时候用?
三、GROUPING SETS:只要精准打击
有时候,你不需要全部组合,只要指定的那几个。
比如:领导只要"按部门"和"总计",不需要按城市。
SELECT dept,SUM(amount) AS amountFROM salesGROUP BY GROUPINGSETS(dept,());()代表总计。
或者这样写也行:
SELECT dept,city,SUM(amount) AS amountFROM salesGROUP BY GROUPINGSETS((dept),(city),());
精准要什么,就给什么。 不多不少。
进阶用法:还能配合ROLLUP/CUBE嵌套
> GROUP BY ROLLUP(dept), GROUPING SETS(city, ())
> 这波操作相当于:按城市明细 + 城市小计 + 总计,不要部门的。
四、GROUPING():区分汇总行和明细行
现在问题来了:汇总行和明细行混在一起,怎么区分?
比如输出里出了NULL——你哪知道这是"城市为NULL"还是"这是汇总行"?
用 GROUPING(col)函数:
SELECT dept, city, SUM(amount) amount, GROUPING(dept) AS dept_total, GROUPING(city) AS city_totalFROM salesGROUP BY CUBE(dept, city);
结果:
dept | city | amount | dept_total | city_total |
|---|
销售部 | 北京 | 10000 | 0 | 0 |
销售部 | NULL | 10000 | 0 | 1 ← 城市汇总 |
NULL | 北京 | 10000 | 1 | 0 ← 部门汇总 |
NULL | NULL | 10000 | 1 | 1 ← 总计 |
|
|
|
|
|
规律:
配合 CASE WHEN,可以把汇总行标记成人类能看懂的文字:
SELECTCASE WHEN GROUPING(dept)=1 THEN'部门合计' ELSE dept END AS dept,CASE WHEN GROUPING(city)=1 THEN'城市合计' ELSE city END AS city,SUM(amount)FROM salesGROUP BY CUBE(dept,city);
再也不会分不清了。
五、进阶神器:GROUPING_ID()
如果你觉得 GROUPING() 一个一个写太麻烦,用 GROUPING_ID():
SELECTdept,city,SUM(amount),GROUPING_ID(dept,city) AS gidFROM salesGROUP BY CUBE(dept,city);
返回的是位运算结果:
gid | 含义 |
|---|
0 | 明细行(dept非汇总 city非汇总) |
1 | city汇总 |
2 | dept汇总 |
3 | 总计 |
一眼就能判断是哪个层级。代码更短,逻辑更清晰。
今天学的这4个函数:
ROLLUP 自动层级汇总
CUBE 全排列组合汇总
GROUPING SETS 自定义要哪些组合
GROUPING() / GROUPING_ID() 区分汇总行和明细行
一个函数,一个SQL,一个结果。
该文章在 2026/5/20 12:56:47 编辑过