PARTITION BY 和 GROUP BY 本质不同:前者是窗口函数参数,不减少行数,必须嵌套在 OVER() 中;后者是独立子句,压缩行数,要求非聚合字段必须出现在 GROUP BY 中。

PARTITION BY 和 GROUP BY 完全不是同一类操作,混用会导致语法报错或逻辑错误——前者必须嵌在 OVER() 里,后者是独立子句;前者不减少行数,后者必然压缩行数。
GROUP BY 报错“Invalid use of group function”或字段不在 SELECT 列表中?
这是最常见误用:把 AVG(salary) 和未聚合的 name、emp_id 同时写在 SELECT 里,又没加 GROUP BY 分组依据。
- 合法写法只允许:
SELECT dept_id, AVG(salary)+GROUP BY dept_id,且所有非聚合字段(如dept_id)必须出现在GROUP BY中 - 想保留每个人信息并附带部门平均工资?不能用 GROUP BY,得换
AVG(salary) OVER (PARTITION BY dept_id) - GROUP BY 执行顺序早于 SELECT,它看到的是原始行;而窗口函数在 SELECT 输出后才计算,能看到已处理过的字段(包括 GROUP BY 聚合后的结果)
PARTITION BY 单独写 SELECT * FROM t PARTITION BY col 就报错?
PARTITION BY 不是独立语法,它只是 OVER() 的一个参数。脱离 OVER() 使用会直接触发 “missing window specification” 类错误。
- 正确结构只有这一种:
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) -
PARTITION BY可以省略(即空着),此时整个结果集视为一个分区,例如COUNT(*) OVER()算总行数 - 多字段分区写成
PARTITION BY region, year,语义等同于先按 region 再按 year 嵌套分组
该用 GROUP BY 还是 PARTITION BY?看输出行数是否允许变化
核心判断标准就一条:你需要最终结果保留原始明细行,还是只要每组一行摘要。
- 要生成报表、统计每个部门总人数/
COUNT(*)、平均薪资/AVG(salary)→ 用GROUP BY - 要给销售订单加一列“本产品历史平均单价”、给用户行为日志加“用户第几次访问”、查每个股票最近 5 日涨跌幅 → 必须用
PARTITION BY配合窗口函数 - 性能上:
GROUP BY在大表常触发排序或哈希分组,内存压力明显;PARTITION BY是分区扫描,若分区键选择不当(比如用低基数字段),可能退化为全表遍历
最容易被忽略的一点:PARTITION BY 的分区边界由数据值决定,不依赖物理存储;而像 MySQL 或 TDengine 中的表级 PARTITION BY(用于建表)是另一回事——那是存储层切分,和窗口函数里的 PARTITION BY 同名不同源,别搞混。










