跳到主要内容

SUM OVER 窗口函数详解

一、一句话理解

SUM() OVER() 在每一行上计算某个窗口范围内的累计和,不折叠数据行。

二、函数语法

SUM(列名) OVER (PARTITION BY 分组列 ORDER BY 排序列 窗口帧)

三、真实业务场景

场景1:累计销售额

按日期排序,计算截止每天的累计销售额。

日期当日销售额累计销售额
1月1日10001000
1月2日15002500
1月3日8003300
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天的移动求和

七、相关面试题

📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

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

交流微信二维码

你可能还想看