讲师中心 微信公众号
AI工具推荐 视频效率加速

SQL中CUBE和GROUPING SETS有什么区别与用法?

阿静小哥_8442

阿静小哥_8442

发布时间:2026-09-18 08:06:37

|

384人浏览过

|

来源于php中文网

原创

CUBE是GROUPING SETS的语法糖,穷举n个字段所有2ⁿ种分组组合;GROUPING SETS需手动指定分组元组,不自动补全;ROLLUP适用于层级维度,CUBE不感知语义关系。

sql中cube和grouping sets有什么区别与用法?

GROUPING SETS 是显式枚举,CUBE 是 2ⁿ 全子集自动生成

CUBE(a, b, c) 本质就是 GROUPING SETS((a,b,c), (a,b), (a,c), (b,c), (a), (b), (c), ()) 的语法糖,它不推理、不筛选,只做穷举。你写 CUBE 就等于告诉数据库:“把这 n 个字段所有是否参与分组的组合都算一遍”。而 GROUPING SETS 要求你手动列出每个想要的分组元组,比如 GROUPING SETS((a,b), (c), ()) —— 它不会多出 (a) 或 (b,c),也不会漏掉你没写的组合。

常见错误是以为 GROUPING SETS((a), (b), (a,b)) 等价于 ROLLUP(a,b),其实不是:ROLLUP(a,b) 还会包含 ()(全表汇总),而 GROUPING SETS 不会,除非你显式写上 ()。

  • CUBE 顺序无关:GROUP BY CUBE(a,b) 和 GROUP BY CUBE(b,a) 结果一致
  • GROUPING SETS 顺序影响可读性,但不影响语义;括号内逗号分隔的列视为一个原子单元,如 GROUPING SETS((a,b), c) 表示“按 a+b 分组”和“按 c 分组”两组
  • 两者都不能嵌套函数表达式直接进 CUBE 列表,比如 CUBE(YEAR(order_date)) 会报错,得先在 SELECT 或子查询里提取为别名

用 CUBE 前必须检查维度基数,否则结果行数爆炸

CUBE 生成 2ⁿ 行聚合结果(n 是字段数),但实际输出行数还取决于各维度的 DISTINCT 值数量。比如 CUBE(region, status, category) 中,region 有 5 个值、status 有 3 个、category 有 50 个,理论最大组合数是 2³ × 5 × 3 × 50 = 6000 行;但如果 category 是 user_id,哪怕只取前 100 个,2³ × 5 × 3 × 100 = 12000 行已可能拖慢查询或触发内存溢出。

真实场景中,CUBE 很容易返回远超预期的行数,尤其当某列含大量 NULL 或高基数时。此时看执行计划没用,得先探查数据分布:

  • 运行 SELECT COUNT(DISTINCT region), COUNT(DISTINCT status), COUNT(DISTINCT category) FROM sales 快速评估
  • 避免把 order_id、user_id、timestamp 这类字段放进 CUBE,哪怕加了 WHERE 过滤也不行——聚合计算仍会全量扫描
  • 在 PostgreSQL 或 SQL Server 中,可用 LIMIT 10 快速看 CUBE 结构,但注意 LIMIT 在聚合后生效,不减少计算量

区分原始 NULL 和 CUBE 生成的 NULL,必须用 GROUPING()

CUBE 输出中某列为 NULL,可能是该维度未参与分组(逻辑占位),也可能是原始数据本来就是 NULL。这两者业务含义完全不同,但表现一样。不加 GROUPING() 函数,你根本无法判断 region IS NULL 的那行到底是“全国汇总”,还是“region 字段缺失的脏数据”。

GROUPING(region) 返回 1 表示这一行的 region 是 CUBE 自动生成的占位值(即该维度被折叠),返回 0 表示它是真实值(哪怕值本身是 NULL)。

  • 务必在 SELECT 列表中包含 GROUPING(col),尤其当需要导出报表或对接 BI 工具时
  • 用 COALESCE(region, 'ALL') 替换逻辑 NULL 时,要同步用 GROUPING(region) = 0 过滤条件保护原始 NULL 不被误标为 'ALL'
  • GROUPING_ID(a,b,c) 可压缩多个 GROUPING() 调用,比如 GROUPING_ID(region,product) 返回 0/1/2/3,对应二进制 00/01/10/11,直接映射分组模式

CUBE 不适合层级关系,该用 ROLLUP 的别硬套

CUBE 对字段间语义完全无感,它只做笛卡尔组合。如果你的维度有天然层级(比如 time: year → quarter → month,或 org: dept → team → person),用 CUBE 会产出大量无业务意义的组合,例如 (year, month) 有值,但 (quarter) 却为空——因为 CUBE 不保证前缀连续性。

这时候 ROLLUP(year, quarter, month) 才是正解:它按顺序生成 (year,quarter,month) → (year,quarter) → (year) → (),天然匹配树状汇总路径。把顺序写反成 ROLLUP(month, quarter, year),结果就只剩 (month)、(month,quarter)、(month,quarter,year)、(),彻底丢失季度和年度独立汇总。

  • ROLLUP 性能通常略优于等效的 GROUPING SETS,在 PostgreSQL 和 SQL Server 中优化器对 ROLLUP 有专属路径
  • MySQL 8.0.12+ 支持 ROLLUP/CUBE,但 WHERE 条件无法下推到 ROLLUP 子分组,可能扫更多行
  • 如果既要层级汇总又要交叉维度(比如时间 + 地区),应拆成 ROLLUP(time_cols), CUBE(region_cols),而不是一股脑塞进一个 CUBE
CUBE 最容易被忽略的点,是它不校验维度间业务关系,也不压缩稀疏组合——哪怕 99% 的 (region, product) 组合在数据里根本不存在,CUBE 依然会为它们生成带 0 值的空行。上线前不跑 GROUPING() 校验、不查基数、不区分 NULL 类型,基本等于埋了个定时查询雪崩。

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4023

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

851

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1049

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5901

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2803

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5880

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7821

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1070

2024.04.29

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

80

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn