PARTITION BY 不能独立使用,必须与窗口函数(如SUM、ROW_NUMBER)配合;它在每个分区内执行函数计算,保留原行数,不同于GROUP BY的行压缩;加ORDER BY实现累计计算,不加则为全量静态小计。

PARTITION BY 本身不统计,必须搭配窗口函数才能算出结果
直接写 PARTITION BY dept_id 是语法错误,它只是 OVER() 子句里的一个可选组件,不能独立存在。真正干活的是前面的函数,比如 SUM()、ROW_NUMBER()、AVG() 等。你看到的“分区统计”,其实是“在每个分区内执行一次窗口函数”。
常见错误:把 PARTITION BY 当成 GROUP BY 用
典型误写:SELECT name, salary, PARTITION BY dept_id FROM employees —— 这会直接报错,因为 PARTITION BY 不是 SELECT 列表里的合法表达式。
- GROUP BY 压缩行数:每组只返回一行,适合做最终汇总
- PARTITION BY 保留原行:每组每行都返回一个计算值,适合加一列“部门总薪资”“组内排名”这种明细增强场景
- 想同时有明细 + 小计?别嵌套 GROUP BY 和 PARTITION BY,用
SUM() OVER (PARTITION BY dept_id)一行搞定
ORDER BY 在 PARTITION BY 后面到底要不要加?
加不加决定计算逻辑是否“滚动”——这是最容易踩坑的地方。
- 不加
ORDER BY(如SUM(salary) OVER (PARTITION BY dept_id)):算的是该分区内所有行的总和,结果每行都一样 - 加了
ORDER BY hire_date(如SUM(salary) OVER (PARTITION BY dept_id ORDER BY hire_date)):默认窗口是ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,变成“按入职时间累计求和”,每行结果不同 - 排序字段含重复值时(比如多人同一天入职),
ORDER BY hire_date可能导致结果不稳定;建议补一个唯一字段,例如ORDER BY hire_date, emp_id
NULL 值在 PARTITION BY 中会被单独分到一组
如果 dept_id 有 NULL,那么所有 dept_id IS NULL 的行会组成一个独立分区,SUM() OVER (PARTITION BY dept_id) 会为它们算出一个“NULL 部门总薪资”。这常被忽略,但线上查数据时可能突然冒出一列非预期的汇总值。
- 想过滤掉 NULL 分区?先用
WHERE dept_id IS NOT NULL - 想把 NULL 归入某组(比如“未分配”)?用
CASE WHEN dept_id IS NULL THEN 'UNASSIGNED' ELSE dept_id END包一层再PARTITION BY - 聚合类窗口函数(
SUM、AVG)默认忽略 NULL 值,但分区键为 NULL 不影响分组逻辑
真正难的不是写法,而是想清楚你要的是“全量静态小计”还是“有序动态累计”——前者不加 ORDER BY,后者必须加,且得确认排序依据是否足够稳定。

















