sql 中的 over() 窗口函数
1. 计算场景
通过 OVER() 指定窗口, 在不减少结果行数的前提下, 对每一行附加计算, 用于:
- 排名 (ROW_NUMBER、RANK)
- 累积和 (sum 等聚合函数)
- 与前一行/后一行 计算环比(LAG/LEAD)
2. 语法
<window_function>([expression])
OVER ([PARTITION BY col1, col2, ...] -- 可选:先按照这些列分区[ORDER BY col3 [ASC|DESC]] -- 可选:在每个分区内排序
)
说明
- PARTITION BY:相当于窗口内的GROUP BY,把数据分成多组,每组独立计算
- ORDER BY:定义在每个窗口内部的排序顺序
3. 举例
约定有这么一张 sales 销售额表, 列名有: (id region month amount)
.
例子1: 计算每月的销售总额, 以及占比.
-- 注意 over() 里面必须为空, 计算全表的 amount, 这样每行分母才一致.
SELECT month,SUM(amount), SUM(amount)/sum(SUM(amount)) OVER () AS ratio
FROM sales
group by month;
当 over( ) 与 group by 搭配时, 注意次序(详见附录)为 先 分组 再 窗口. 所以可以 sum套 sum.
例子2: 计算一个部门, 从年初到当月的累积销售额
-- over( order by) 是有序累计.SELECT month,sum(amount) OVER (month asc) AS 累积销售额
FROM sales
where region = '某部门';
4. 附录
sql 执行次序
1. FROM / JOIN -- 先确定数据来源
2. WHERE -- 过滤原始行
3. GROUP BY -- 分组
4. 聚合函数计算 -- SUM, COUNT 等
5. HAVING -- 对分组结果过滤
6. 窗口函数 (OVER) -- 在当前结果集上按窗口计算
7. SELECT -- 投影出需要的列
8. ORDER BY -- 按指定顺序排序
9. LIMIT / OFFSET -- 限制输出行数