SUM OVER 窗口函数详解
一、一句话理解
SUM() OVER() 在每一行上计算某个窗口范围内的累计和,不折叠数据行。
二、函数语法
SUM(列名) OVER (PARTITION BY 分组列 ORDER BY 排序列 窗口帧)
三、真实业务场景
场景1:累计销售额
按日期排序,计算截止每天的累计销售额。
| 日期 | 当日销售额 | 累计销售额 |
|---|---|---|
| 1月1日 | 1000 | 1000 |
| 1月2日 | 1500 | 2500 |
| 1月3日 | 800 | 3300 |
SELECT date, daily_sales,
SUM(daily_sales) OVER (ORDER BY date) AS cumulative_sales
FROM sales;
场景2:各部门薪资占比
每个员工的薪资占所在部门总薪资的百分比。
SELECT dept, name, salary,
SUM(salary) OVER (PARTITION BY dept) AS dept_total,
ROUND(salary * 100.0 / SUM(salary) OVER (PARTITION BY dept), 1) AS pct
FROM employee;
场景3:近 3 天移动求和
每行显示最近 3 天(含当天)的销售额总和。
SELECT date, daily_sales,
SUM(daily_sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS rolling_3day_sum
FROM sales;
四、窗口帧对 SUM 的影响
| 窗口帧 | 含义 | 结果 |
|---|---|---|
| 无(默认) | 分区开始到当前行 | 累计求和 |
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING | 整个分区 | 等于 GROUP BY SUM |
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW | 前2行+当前行 | 近3天滚动 |
五、常见坑点
坑1:ORDER BY 会改变默认窗口帧
不加 ORDER BY → 整个分区求和。加了 ORDER BY → 默认窗口帧缩为"分区开始到当前行",变成累计求和。这是最常见的困惑点。
坑2:SUM OVER 不能替代 GROUP BY
SUM OVER 保留每行明细,GROUP BY 折叠行。两者用途不同,不存在谁替代谁。
六、面试怎么考
- "怎么算累计销售额?" → SUM OVER + ORDER BY
- "SUM OVER 和 GROUP BY SUM 有什么区别?" → 是否折叠行
- "ROWS BETWEEN 怎么用?" → 近N天的移动求和
七、相关面试题
- 07. 每个城市销售额排名及占比 — SUM OVER 分区聚合
- 06. 用户搜索session切分 — SUM OVER 累计分组
- 04. 篮球比赛得分分析 — SUM OVER 连续得分
- 更多窗口函数面试题 →
📱关注公众号
「数据仓库技术」文章同步更新,不错过每一篇干货

💬加群交流
备注「数据仓库技术」加入社群,每日一道大厂SQL真题
