news 2026/9/4 20:37:58

SUM OVER 累加与 ROWS BETWEEN 窗口边界:彻底搞懂滑动窗口的五种语法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SUM OVER 累加与 ROWS BETWEEN 窗口边界:彻底搞懂滑动窗口的五种语法

SUM OVER 累加与 ROWS BETWEEN 窗口边界:彻底搞懂滑动窗口的五种语法

在日常 SQL 数据分析中,求“累计销售总额(Running Total)”、“移动平滑均值(Moving Average)”或者“区间最大回撤”是极其高频的统计需求。

很多熟练使用SUM() OVER(PARTITION BY ... ORDER BY ...)的工程师,在被问到以下细节时往往会语塞:

  • 为什么不加ROWS BETWEEN时,如果排序列有相同的值,SUM()会把相同日期的金额一次性全加起来?
  • ROWS BETWEENRANGE BETWEEN到底有什么本质区别?
  • 怎么用一条 SQL 算出“包含当天在内过去 7 天的动态滑动窗口销售额”?

如果对窗口边界(Window Frame Clause)的底层机制缺乏清晰认知,写出的累计指标很容易在遇到并列数据、缺失日期或海量数据聚合时产生隐蔽的统计偏差。

今天我们系统拆解OVER()子句中窗口边界定义的完整语法体系与五大实战范式。


窗口边界语法的通用骨架

一个完整的分析窗口定义由三个部分构成:

函数名() OVER ( PARTITION BY 分区字段 ORDER BY 排序字段 [ASC|DESC] [ROWS | RANGE] BETWEEN 窗口起始边界 AND 窗口结束边界 )

核心关键字字典:

  • CURRENT ROW:当前行
  • UNBOUNDED PRECEDING:分区内的第一行(无上界起点)
  • UNBOUNDED FOLLOWING:分区内的最后一行(无下界终点)
  • N PRECEDING:当前行向前偏移 $N$ 行/单位
  • N FOLLOWING:当前行向后偏移 $N$ 行/单位

必须掌握的五大经典窗口边界模式

假设我们有一张简单的日销售明细表t_sales_daily(dt, amount)

模式一:标准累计求和(从月初第一天累加到当天)

SELECT dt, amount, -- 语法 A:显式声明物理行边界(最安全、最推荐的标准写法) SUM(amount) OVER ( ORDER BY dt ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS running_total_amount FROM t_sales_daily;

模式二:滑动居中平均(前 1 天 + 当天 + 后 1 天,共 3 天居中窗口)

常用于时序数据平滑滤波,消除单日随机波动:

SELECT dt, amount, -- 窗口跨度:包含前 1 行、当前行、后 1 行 AVG(amount) OVER ( ORDER BY dt ASC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) AS moving_avg_3d_centered FROM t_sales_daily;

模式三:回溯滑动窗口(包含当天在内的过去 7 天累计)

业务场景:监控任意一天的“过去 7 天滚动总营收”:

SELECT dt, amount, -- 窗口跨度:从前 6 行到当前行(共 7 行) SUM(amount) OVER ( ORDER BY dt ASC ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ) AS rolling_sum_7d FROM t_sales_daily;

模式四:全分区全局聚合(同时获取明细与总体占比)

业务场景:在每一行明细旁边直接展示该单金额占全月大盘总金额的百分比,无需单独写子查询:

SELECT dt, amount, -- 全局求和:从分区第一行到最后一行 SUM(amount) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS grand_total_amount, -- 直接计算单日销售贡献占比 ROUND( amount / SUM(amount) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) * 100, 2 ) AS contribution_pct FROM t_sales_daily;

模式五:前向累计(从当前天到月底最后一天,剩余指标预测)

业务场景:计算当月后续剩余天数的销售目标缺口:

SELECT dt, amount, -- 从当前行累加到分区最后一行 SUM(amount) OVER ( ORDER BY dt ASC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) AS remaining_month_total FROM t_sales_daily;

致命大坑:ROWSvsRANGE的暗坑差异

这是无数初学者甚至工作三年的老手都会踩翻的经典事故!

现象实测:

如果我们在写SUM(amount) OVER (ORDER BY dt)省略了ROWS BETWEEN,SQL 标准(ANSI SQL)默认采用的缺省边界是:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(注意是RANGE而不是ROWS!)。

测试数据: 日期 (dt) | 金额 (amount) 2026-09-04 | 100 2026-09-04 | 200 <-- 存在相同日期! 2026-09-05 | 300
  • 如果使用ROWS BETWEEN ...(按物理行数累加)
    第 1 行结果:100
    第 2 行结果:100 + 200 =300
    第 3 行结果:300 + 300 = 600
  • 如果不写,默认变成RANGE BETWEEN ...(按逻辑数值范围累加)
    因为第 1 行和第 2 行的dt值完全相同,RANGE认为它们属于同一个“同级数值组(Peers)”,会在这一步直接把相同日期的所有金额全加起来!
    第 1 行结果:300(提前加了第 2 行!)
    第 2 行结果:300
    第 3 行结果:600

事故后果:如果表里有重复排序列,省略ROWS BETWEEN会导致中间行的累计值出现虚假的并列跳变,完全破坏了按行逐步递增的财务审计要求!


终极军规

  1. 永远显式书写ROWS BETWEEN:在任何需要严格行级累加的 SQL 中,坚决不要依赖默认行为,完整敲出ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2. 复用命名窗口(Window Specification):当一个查询中需要同时计算多个相同窗口维度的指标时,使用WINDOW w AS (...)提高可读性并提升优化器执行效率:
    SELECT dt, SUM(amount) OVER w AS run_sum, AVG(amount) OVER w AS run_avg, MAX(amount) OVER w AS run_max FROM t_sales_daily WINDOW w AS (ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 20:29:42

基于YOLOv8的安全帽工作服检测:从算法原理到工业部署实战

简介&#xff1a;本资源是一套基于YOLOv8实现的安全帽与工作服双目标检测的完整Python工程&#xff0c;面向计算机、电子信息、人工智能等专业的本科生及研究生&#xff0c;适用于课程设计、期末大作业与毕业设计等实践场景&#xff0c;解决施工现场人员防护装备合规性智能识别…

作者头像 李华
网站建设 2026/9/4 20:25:58

电竞服务平台源码解析:从技术选型到运营部署的完整指南

简介&#xff1a;这是一套面向电竞俱乐部、陪玩工作室及游戏代练平台的商业化护航系统源码&#xff0c;聚焦解决从个人接单向平台化运营转型中的核心痛点——订单派发低效、客服验收缺失、风控能力薄弱及数据统计断层。系统覆盖陪玩代练、三角洲行动护航、俱乐部定制陪练等多场…

作者头像 李华
网站建设 2026/9/4 20:24:24

Java实战:基于领域驱动与SQLite的个人信息管理系统设计与实现

简介&#xff1a;本资源是一个面向Java初学者与高校课程设计学生的个人信息维护系统实践项目&#xff0c;聚焦Web应用开发全流程训练&#xff0c;涵盖用户登录、信息展示与修改、登录日志查询等核心功能&#xff0c;帮助学习者掌握JDBC数据库操作、MVC分层架构、前后端交互及基…

作者头像 李华
网站建设 2026/9/4 20:20:43

基于Flask与Spark的Steam游戏数据分析平台全栈实战

简介&#xff1a;本资源是一个面向数据分析初学者与Web开发学习者的综合性实战项目&#xff0c;聚焦Steam游戏市场趋势与用户行为挖掘&#xff0c;完整覆盖数据爬取、存储、清洗、分析到可视化展示的全流程。项目基于Flask构建轻量级Web平台&#xff0c;融合大数据处理思路&…

作者头像 李华
网站建设 2026/9/4 20:18:15

微信小程序图像识别工程化实践:从API调用到落地交付

简介&#xff1a;本资源是一套完整的微信小程序图像识别实战源码&#xff0c;面向前端开发者与AI应用初学者&#xff0c;解决轻量级移动端图像智能分析的集成难题。项目基于微信小程序框架&#xff0c;深度整合百度AI开放平台接口&#xff0c;实现图片上传、缩略图自适应显示、…

作者头像 李华