PARTITION BY 按指定列分组实现分组内逐行计算,不减少行数;逻辑顺序为先分区、再排序、最后定义窗口帧;NULL值自动归为同一分区,多列分区时含NULL的组合仍混入同一隐式组。

PARTITION BY 的作用是把数据按指定列分组,窗口函数在每个分组内独立计算,不改变原表行数,也不做聚合(除非配合聚合函数使用)。
它不是分组聚合,而是“分组内逐行计算”
PARTITION BY 不会像 GROUP BY 那样压缩行数。原始有多少行,结果还是多少行;只是每行的计算范围被限制在所属分区内部。
- 例如:
COUNT(*) OVER (PARTITION BY dept)对每个员工返回其所在部门的总人数,每人一行,不是只返回一个数字 - 而
GROUP BY dept; COUNT(*)会变成一行一个部门,行数减少
执行顺序上,PARTITION BY 在 ORDER BY 和 ROWS/RANGE 之前生效
窗口函数实际执行时,逻辑顺序是:先按 PARTITION BY 拆出若干子集 → 再在每个子集中按 ORDER BY 排序 → 最后按 ROWS BETWEEN 或 RANGE 定义窗口帧(frame)→ 执行函数计算。
- 没写 ORDER BY 时,分区内的行顺序不确定(取决于底层扫描顺序),可能导致结果不稳定
- 没写 ROWS/RANGE 时,默认是
UNBOUNDED PRECEDING TO CURRENT ROW(累计窗口)
NULL 值会被归为同一组
PARTITION BY 列值为 NULL 的所有行,会被划入同一个隐式分区。这和 GROUP BY 中 NULL 被视为相等一致。
- 如果 dept 是 NULL,所有 dept IS NULL 的记录会组成一个分区,COUNT、SUM 等都在这个 NULL 分区内算
- 想排除 NULL,可加 WHERE dept IS NOT NULL,或用 CASE 包装分区键(如
PARTITION BY COALESCE(dept, 'UNKNOWN'))
可以多列组合分区,语义是“完全匹配才同组”
PARTITION BY dept, region 表示只有 dept 和 region 都相同的行才属于同一分区,等价于联合主键匹配。
- 注意:多列分区时,任意一列是 NULL,整组比较就为 UNKNOWN,这些行仍会被归进同一个 NULL 组(即 (NULL, NULL)、(NULL, 'A')、('B', NULL) 全部混在一起)
- 如需严格分离,建议提前用 COALESCE 或 CASE 处理 NULL










