sum() over(order by ...)实现逐行累计求和,即按指定顺序(如date)从首行加至当前行;必须显式指定order by,否则返回分区总和而非累计值,且需确保排序字段语义明确、无歧义、有索引支持。

什么是SUM窗口函数的累计求和效果
用 SUM() 配合 OVER() 就能实现累计求和,它不是对整列求和,而是按指定顺序逐行累加——比如按日期排序后,每行显示“从第一行到当前行”的总和。关键在于 ORDER BY 必须出现在 OVER 子句里,否则结果是整组静态和,不是累计。
SUM() OVER(ORDER BY ...) 的基本写法
最简可用形式就是:SUM(value) OVER (ORDER BY date)。这里 date 是排序依据字段,决定“累计”的顺序。如果没加 PARTITION BY,整个结果集视为一个分区;加了就按分组分别累计。
-
ORDER BY字段必须有明确排序语义(如时间、序号),不能是随机值或重复率极高的字段,否则累计顺序不可靠 - 若存在相同
ORDER BY值(比如同一天多条记录),SQL 标准不保证这些行之间的累加先后,实际执行可能因引擎而异 - 想强制稳定顺序,可追加唯一字段:例如
ORDER BY date, id
常见错误:漏掉 ORDER BY 或写错范围
直接写 SUM(value) OVER () 会返回每行都是全量和,不是累计;写成 SUM(value) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 虽然等价但冗余——这是默认行为,不用显式写出。
- 错误示例:
SUM(sales) OVER (PARTITION BY region)→ 缺少ORDER BY,每个区域只返回该区域总和,不是逐行累计 - 错误示例:
SUM(sales) OVER (ORDER BY date DESC)→ 累计方向反了,最新日期排第一,它的累计值只有自己 - MySQL 8.0+、PostgreSQL、SQL Server 都支持;SQLite 3.25+ 支持,但旧版不支持窗口函数
性能与数据类型注意事项
累计求和本质是顺序扫描 + 累加,大数据量时依赖排序字段是否有索引。如果 ORDER BY 字段没索引,执行计划里可能出现 Sort 操作,拖慢查询。
-
SUM()对NULL值自动跳过,但如果所有前置行都是NULL,当前行为NULL(不是 0) - 输入列如果是
DECIMAL或FLOAT,输出精度继承原类型;整数列相加不会自动转为浮点 - 在分页场景中慎用:
LIMIT/OFFSET在窗口函数之后生效,累计和计算仍基于全集,不是仅当前页











