首页/数据/SQL 速查/GROUPING() 区分小计行
聚合与窗口函数54 条

GROUPING() 区分小计行

GROUPING(列) 在超级聚合(小计/合计)行返回 1、普通行返回 0,用来把 NULL 与小计正确区分开。

SQL 速查数据更新于 2026-10-13

GROUPING 区分汇总行

GROUPING(列) 用来区分普通行与超级聚合行:配合 WITH ROLLUP 或 GROUPING SETS 使用时,小计与合计行返回 1,普通行返回 0。它的价值是把「本来就是 NULL」和「因为汇总而显示为空」分开,报表里不至于把合计行当成某个具体分组。

基本信息

返回值0 表示普通行,1 表示该列被汇总的超聚合行
使用前提查询里要用 ROLLUP 或 GROUPING SETS
适用平台MySQL 8 与 PostgreSQL 均可用
用途标注汇总行、过滤小计与合计
配套语法GROUPING SETS、ROLLUP、CUBE

典型使用场景

  • 报表里标注「合计」这类标签
  • 把合计行排除在明细统计之外
  • 多层小计:城市小计加全国合计
  • 输出到前端时区分汇总层级
  • 排查合计行与真实 NULL 混淆导致的口径错误

示例

示例
-- WITH ROLLUP 生成小计与合计行,用 GROUPING 区分
SELECT city,
       GROUPING(city) AS is_total,     -- 1 表示这行是汇总行
       COUNT(*)       AS cnt
FROM users
GROUP BY city WITH ROLLUP;

-- 只保留明细行,过滤掉小计与合计
SELECT city, COUNT(*) AS cnt
FROM users
GROUP BY city WITH ROLLUP
HAVING GROUPING(city) = 0;

相关语法的作用

语法生成什么配合 GROUPING 做什么
WITH ROLLUP逐层小计加总合计行标注汇总行、过滤汇总行
GROUPING SETS指定多组分组组合分辨当前行属于哪一组
CUBE所有列组合的汇总在多维分析里定位汇总层级
单独 GROUP BY只有普通行GROUPING 恒为 0,没有意义
没有 ROLLUP 或 GROUPING SETS 时 GROUPING() 没有意义:它只在超级聚合行返回 1,普通分组查询上给不出有用信息。
报表排序要一并处理:汇总行默认按分组键排,可能插在明细中间。通常在 ORDER BY 里加上汇总行标记,让合计行稳定落在末尾。
把结果输出到前端时建议额外给一个层级标记列:只提供汇总标记、让前端自己推断层级,遇到多层汇总时很容易展示错位。
不同实现对 GROUPING 参数的接受度有差异:有的支持一次判断多个列,有的只接受单个列,跨库写法前先按目标库的语法验证一遍。

易错点

  • 把 GROUPING() 用在没有 ROLLUP 或 GROUPING SETS 的查询上:拿不到有意义的结果,多数场景直接报错
  • 用汇总行做明细统计:合计行被重复计入,总数直接偏大,需要用 GROUPING 过滤
  • 过滤汇总行后忘了处理排序:小计行可能排到中间,报表可读性变差
  • 把汇总产生的 NULL 当成真实空值:业务列本身也可能为 NULL,必须靠 GROUPING 区分
  • 多层汇总不逐列判断:每一列的 GROUPING 都要单独看,只看一列会误判层级

数据来源与参考

  • MySQL 8.0 Reference Manual · GROUPING Function
  • PostgreSQL Documentation · GROUPING Function
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌