2. 窗口函数基础回顾:OVER() 子句、PARTITION BY、ORDER BY、窗口帧(ROWS/RANGE)核心概念
窗口函数是 SQL 中用于在保持行级粒度的同时,对“窗口”内的行执行聚合、排序或偏移计算的函数。其核心语法围绕 OVER() 子句展开,理解 PARTITION BY、ORDER BY 和窗口帧(Frame)是掌握窗口函数的基础。
2.1 OVER() 子句:窗口函数的入口
所有窗口函数都必须通过 OVER() 子句定义其计算范围。空括号 OVER() 表示将整个结果集视为一个窗口,对所有行执行计算。
基本语法结构:
<窗口函数> OVER (
[PARTITION BY <列名>]
[ORDER BY <列名> [ASC|DESC]]
[<窗口帧定义>]
)
2.2 PARTITION BY:分组边界
PARTITION BY 将结果集划分为多个逻辑分区(组)。窗口函数在每个分区内独立计算,分区之间互不影响。若省略 PARTITION BY,则整个结果集视为一个分区。
| 特性 | 说明 | 示例 |
|---|---|---|
| 分组依据 | 按指定列的值分组,相同值的行进入同一分区 | PARTITION BY department_id |
| 独立性 | 每个分区独立排序、独立计算窗口帧 | 部门内排名互不影响 |
| 与 GROUP BY 区别 | 不减少行数,保留所有原始行 | 每行都保留,同时获得聚合值 |
2.3 ORDER BY:排序与窗口帧锚点
ORDER BY 在窗口内定义行的排序顺序。它不仅影响排名函数的结果,还决定了窗口帧的起始与结束边界(当使用 ROWS 或 RANGE 时)。
- 排名函数:
ROW_NUMBER()、RANK()、DENSE_RANK()依赖ORDER BY生成顺序编号。 - 偏移函数:
LAG()、LEAD()依赖ORDER BY确定“前一行”或“后一行”的位置。 - 聚合窗口函数:
SUM()、AVG()等配合ORDER BY可实现累计计算。
注意: 当
ORDER BY 与窗口帧同时省略时,默认窗口为整个分区;当 ORDER BY 存在但窗口帧省略时,默认窗口帧为 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。
2.4 窗口帧(Frame):精确控制行范围
窗口帧在 PARTITION BY 和 ORDER BY 的基础上,进一步限定参与计算的行集合。帧定义使用 ROWS 或 RANGE 关键字,配合边界关键字 UNBOUNDED PRECEDING、n PRECEDING、CURRENT ROW、n FOLLOWING、UNBOUNDED FOLLOWING。
| 帧模式 | 含义 | 适用场景 |
|---|---|---|
ROWS |
基于物理行偏移,精确指定前后行数 | 固定窗口大小(如最近3行移动平均) |
RANGE |
基于逻辑值范围,相同排序值的行视为一组 | 按值范围累计(如日期区间累计) |
常见窗口帧定义示例
-- 默认帧(有 ORDER BY 时)
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-- 固定前3行
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
-- 前后各2行
ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING
-- 整个分区
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-- 按值范围:当前行值 ± 10
RANGE BETWEEN 10 PRECEDING AND 10 FOLLOWING
易错点:
RANGE 模式下,若 ORDER BY 列存在重复值,则所有重复值行会被同时包含或排除,可能导致窗口大小超出预期。在特征稳定性分析中,建议优先使用 ROWS 模式以保证窗口边界确定。
2.5 窗口帧边界关键字速查
| 边界关键字 | 含义 | 示例 |
|---|---|---|
UNBOUNDED PRECEDING |
分区第一行 | 从分区起点开始 |
n PRECEDING |
当前行之前的第 n 行 | 3 PRECEDING 表示前3行 |
CURRENT ROW |
当前行 | 窗口的基准行 |
n FOLLOWING |
当前行之后的第 n 行 | 2 FOLLOWING 表示后2行 |
UNBOUNDED FOLLOWING |
分区最后一行 | 到分区终点结束 |
2.6 窗口函数在特征稳定性分析中的角色
在批次偏移诊断中,窗口函数用于:
- 计算批次间统计量变化:使用
LAG()获取上一批次的特征均值、标准差,计算偏移量。 - 生成累计分布:使用
SUM() OVER(ORDER BY batch_id)计算特征值的累计占比。 - 滑动窗口监控:使用
AVG() OVER(ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)计算滑动平均,平滑短期波动。 - 分区对比:使用
PARTITION BY feature_name对不同特征独立计算稳定性指标。
实战提示: 在特征稳定性分析中,
PARTITION BY 通常按特征名称或批次分组,ORDER BY 按时间或批次序号排序,窗口帧则根据分析窗口长度(如最近10个批次)设定。合理选择 ROWS 与 RANGE 直接影响偏移检测的灵敏度。