mysql 的分组函数 ROLLUP 语法

  • Oracle: GROUP BY ROLLUP(字段A)

  • MySQL: GROUP BY 字段A WITH ROLLUP

解决方案1:使用 WITH ROLLUPGROUPING()

sql 复制代码
SELECT 
    CASE 
        WHEN GROUPING(C_JXDM) = 1 THEN 2
        ELSE 0 
    END AS N_GROUPING,
    -- GROUPING(C_JXDM) C_JXDM_GROUPING,
    -- GROUPING(C_PXLB) C_PXLB_GROUPING,
    COALESCE(C_JXDM, '合计') AS C_JXDM,
    COALESCE(C_PXLB, '') AS C_PXLB,
    COUNT(*) AS N_CNT
FROM (
    -- 模拟你的数据表
    SELECT 'name1' AS name, '103001' AS C_JXDM, '1' AS C_PXLB
    UNION ALL
    SELECT 'name2', '103001', '1'
    UNION ALL
    SELECT 'name3', '103001', '2'
    UNION ALL
    SELECT 'name4', '103001', '3'
    UNION ALL
    SELECT 'name5', '103001', '3'
    UNION ALL
    SELECT 'name6', '112001', '1'
    UNION ALL
    SELECT 'name7', '112001', '1'
    UNION ALL
    SELECT 'name8', '138001', '2'
) AS t
GROUP BY C_JXDM, C_PXLB WITH ROLLUP
HAVING GROUPING(C_PXLB) = 0 OR (GROUPING(C_JXDM) = 1 AND GROUPING(C_PXLB) = 1)
ORDER BY 
    GROUPING(C_JXDM) ASC,
    C_JXDM,
    GROUPING(C_PXLB) ASC,
    C_PXLB;
sql 复制代码
N_GROUPING	C_JXDM	C_PXLB	N_CNT
0	103001	1	2
0	103001	2	1
0	103001	3	2
0	112001	1	2
0	138001	2	1
2	合计		8

解决方案2:更简洁的写法(MySQL 8.0+)

sql 复制代码
WITH sample_data AS (
    SELECT 'name1' AS name, '103001' AS C_JXDM, '1' AS C_PXLB
    UNION ALL SELECT 'name2', '103001', '1'
    UNION ALL SELECT 'name3', '103001', '2'
    UNION ALL SELECT 'name4', '103001', '3'
    UNION ALL SELECT 'name5', '103001', '3'
    UNION ALL SELECT 'name6', '112001', '1'
    UNION ALL SELECT 'name7', '112001', '1'
    UNION ALL SELECT 'name8', '138001', '2'
)
SELECT 
    CASE 
        WHEN GROUPING(C_JXDM) = 1 THEN 2
        WHEN GROUPING(C_PXLB) = 0 THEN 0
        ELSE 1
    END AS N_GROUPING,
    -- GROUPING(C_JXDM) C_JXDM_GROUPING,
    -- GROUPING(C_PXLB) C_PXLB_GROUPING,
    COALESCE(C_JXDM, '合计') AS C_JXDM,
    COALESCE(C_PXLB, '') AS C_PXLB,
    COUNT(*) AS N_CNT
FROM sample_data
GROUP BY C_JXDM, C_PXLB WITH ROLLUP
-- HAVING GROUPING(C_PXLB) = 0 OR (GROUPING(C_JXDM) = 1 AND GROUPING(C_PXLB) = 1)
ORDER BY 
    GROUPING(C_JXDM),
    C_JXDM,
    GROUPING(C_PXLB),
    C_PXLB;
sql 复制代码
N_GROUPING	C_JXDM	C_PXLB	N_CNT
0	103001	1	2
0	103001	2	1
0	103001	3	2
1	103001		5
0	112001	1	2
1	112001		2
0	138001	2	1
1	138001		1
2	合计		8

加上"HAVING GROUPING(C_PXLB) = 0 OR (GROUPING(C_JXDM) = 1 AND GROUPING(C_PXLB) = 1)" 就只列出明细和总计行

解决方案3:如果只需要明细和总计(2级汇总)

sql 复制代码
WITH sample_data AS (
    SELECT 'name1' AS name, '103001' AS C_JXDM, '1' AS C_PXLB
    UNION ALL SELECT 'name2', '103001', '1'
    UNION ALL SELECT 'name3', '103001', '2'
    UNION ALL SELECT 'name4', '103001', '3'
    UNION ALL SELECT 'name5', '103001', '3'
    UNION ALL SELECT 'name6', '112001', '1'
    UNION ALL SELECT 'name7', '112001', '1'
    UNION ALL SELECT 'name8', '138001', '2'
)
SELECT 
    GROUPING(C_JXDM) + GROUPING(C_PXLB) AS N_GROUPING,
    IFNULL(C_JXDM, '合计') AS C_JXDM,
    IFNULL(C_PXLB, '') AS C_PXLB,
    COUNT(*) AS N_CNT
FROM sample_data
GROUP BY C_JXDM, C_PXLB WITH ROLLUP
HAVING (GROUPING(C_JXDM) = 0 AND GROUPING(C_PXLB) = 0)  -- 明细行
    OR (GROUPING(C_JXDM) = 1 AND GROUPING(C_PXLB) = 1)  -- 总计行
ORDER BY GROUPING(C_JXDM), C_JXDM, GROUPING(C_PXLB), C_PXLB;

N_GROUPING	C_JXDM	C_PXLB	N_CNT
0	103001	1	2
0	103001	2	1
0	103001	3	2
0	112001	1	2
0	138001	2	1
2	合计		8

解释:

  1. N_GROUPING 值

    • 0:表示明细行(既有C_JXDM分组,也有C_PXLB分组)

    • 2:表示总计行(两个维度都汇总了)

  2. GROUPING() 函数

    • 返回0表示该列参与分组

    • 返回1表示该列是ROLLUP汇总的结果

  3. COALESCE/IFNULL:用于处理ROLLUP产生的NULL值

  4. HAVING 子句

    • 过滤掉中间的汇总行(如每个C_JXDM的小计),只保留明细和最终总计

如果你需要不同级别的汇总(如小计+总计),可以调整HAVING子句的条件。

相关推荐
fen_fen1 天前
Oracle建表语句示例
数据库·oracle
砚边数影1 天前
数据可视化入门:Matplotlib 基础语法与折线图绘制
数据库·信息可视化·matplotlib·数据可视化·kingbase·数据库平替用金仓·金仓数据库
orange_tt1 天前
Djiango配置Celery
数据库·sqlite
云小逸1 天前
【nmap源码学习】 Nmap网络扫描工具深度解析:从基础参数到核心扫描逻辑
网络·数据库·学习
·云扬·1 天前
MySQL Binlog落盘机制深度解析:性能与安全性的平衡艺术
android·mysql·adb
肉包_5111 天前
两个数据库互锁,用全局变量互锁会偶发软件卡死
开发语言·数据库·c++
霖霖总总1 天前
[小技巧64]深入解析 MySQL InnoDB 的 Checkpoint 机制:原理、类型与调优
数据库·mysql
此刻你1 天前
常用的 SQL 语句
数据库·sql·oracle
それども1 天前
分库分表的事务问题 - 怎么实现事务
java·数据库·mysql
·云扬·1 天前
MySQL Binlog 配置指南与核心作用解析
数据库·mysql·adb