SUM() OVER()是窗口函数用法,非独立函数,必须写成SUM(column_name) OVER(...);漏字段、错括号或数据库不支持均会报错。
SUM(OVER) 本质是 SUM() 配合 OVER 子句构成的窗口函数,不是单独存在的函数。直接写 SUM(OVER ...) 会报错——必须写成 SUM(column_name) OVER (...)。
常见错误现象:ERROR: syntax error at or near "OVER",往往是因为漏了括号内的求和字段,或把 OVER 当成 SUM 的参数。
SUM(sales) OVER (ORDER BY date) ✅ 正确:对 sales 按日期累加SUM OVER (ORDER BY date) ❌ 错误:缺少被聚合的列SUM(sales OVER (ORDER BY date)) ❌ 错误:OVER 不能套在括号里当参数累加的核心是定义“按什么顺序加”和“是否分组重置”。不加 ORDER BY,SUM() OVER() 等价于全表总和;加上 ORDER BY 才形成逐行累加。
典型场景:销售日报表中计算截至当日的累计销售额。
SUM(amount) OVER (ORDER BY order_date) → 全局按日期递增累加SUM(amount) OVER (PARTITION BY region ORDER BY order_date) → 每个地区内独立累加SUM(amount) OVER (),结果每行都是同一值(全表总和),不是累加注意:ORDER BY 列必须有确定排序(避免相同值导致非确定性累加),必要时加唯一键如 ORDER BY order_date, id。
累加结果异常,90% 出现在三类情况:空值参与计算、排序键重复、没意识到默认框架是 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。
NULL 值会被忽略(不影响累加),但如果想把 NULL 当 0 处理,得先用 COALESCE(amount, 0)
ORDER BY 字段存在重复(如多笔订单同一天),数据库可能任意打乱这些行顺序,导致累加值“跳变”或不稳定ROWS BETWEEN 1 PRECEDING AND CURRENT ROW,否则始终是“从开头到当前行”示例(PostgreSQL/MySQL 8.0+/SQL Server):
SELECT date, sales, SUM(sales) OVER (ORDER BY date, id) AS cumsumFROM daily_sales;
语法一致,但兼容性差别大:MySQL 5.7 不支持,必须 8.0+;SQLite 直到 3.25+ 才支持窗口函数;Oracle 和 SQL Server 支持较早(2005+),但旧版本可能不支持 ROWS 框架子句。
SELECT VERSION();(MySQL)、SELECT @@VERSION;(SQL Server)ENABLE_WINDOW_FUNCTIONS
@cumsum := @cumsum + sales),但不可靠且非标准真正麻烦的不是语法写不对,而是查了半天发现数据库压根不认 OVER —— 动手前先验证环境支持比调逻辑更重要。