LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

别再死记 SQL 了:一条示例看懂 OVER 窗口函数到底在算什么

admin
2026年2月11日 12:8 本文热度 65

很多人第一次接触 OVER,都是在做类似这样的需求:

  • 每个月的累计用户数

  • 截止当月的累计收入

  • 按时间滚动的统计指标

SQL 能写出来,但一旦结果不对,就开始怀疑人生。

问题通常不在 SQL 技巧,而在于——
没有真正理解 OVER 在“看哪一批数据”。

这篇文章,我们只用一套极简、脱敏、为讲解而设计的 SQL,把 OVER 的计算逻辑彻底讲清楚。


一、一个刻意简化的业务场景

假设有一张订单表,记录每天产生的订单金额:

order_table

字段名含义
order_date订单日期
order_amount订单金额

我们要做的统计是:

统计每个月的订单总额,并计算“截至当月月底”的累计订单金额。

注意这个关键词:
截至当月月底(累计)


二、第一步:只算“每个月新增”(不用 OVER)

先把“每个月新增金额”算清楚。

SELECT
    DATE_FORMAT(order_date, '%Y-%m') AS month_time,
    SUM(order_amount) AS month_amount
FROM order_table
GROUP BY DATE_FORMAT(order_date, '%Y-%m')
ORDER BY month_time;

这一步做的事情非常纯粹:

  • 不涉及历史

  • 不涉及累计

  • 只是把“散落在每天的数据”压缩成“每个月一行”

结果类似:

month_timemonth_amount
2025-0110000
2025-0215000
2025-0312000

三、问题来了:怎么得到“截至当月的累计值”?

很多人第一反应是:

能不能在 GROUP BY 里顺手算一下?

答案是:不行。

GROUP BY 的职责只有一个:
把多行压成一行

而“累计”这件事,本质是:

站在当前这一行,回头看历史所有行。

这正是窗口函数存在的意义。


四、OVER 的登场:窗口是怎么“打开”的

我们把上一步的结果作为一个“月度数据集”,再加一层查询:

SELECT
    month_time,
    month_amount,
    SUM(month_amount) OVER (
        ORDER BY month_time
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS total_amount_at_month_end
FROM (
    SELECT
        DATE_FORMAT(order_date, '%Y-%m') AS month_time,
        SUM(order_amount) AS month_amount
    FROM order_table
    GROUP BY DATE_FORMAT(order_date, '%Y-%m')
) t
ORDER BY month_time;

这条 SQL 就是理解 OVER 的最佳切入口


五、一句一句拆解 OVER 在干什么

1️⃣ SUM(month_amount)

这不是重点,它只是一个普通聚合函数。

重点在后面的 OVER


2️⃣ ORDER BY month_time

这一句在说:

累计是有方向的,按月份从早到晚算。

没有它,就不存在“累计”的概念。


3️⃣ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

这是整条 SQL 的灵魂。

直译成中文就是:

从第一行开始,一直算到当前这一行。

换成业务语言:

历史所有月份 + 当前月份


六、用“人脑视角”看窗口是如何滑动的

假设月度数据是这样:

month_timemonth_amount
2025-0110000
2025-0215000
2025-0312000

窗口函数在每一行看到的数据是:

  • 2025-01
     窗口 = [2025-01]
     累计 = 10000

  • 2025-02
     窗口 = [2025-01 → 2025-02]
     累计 = 25000

  • 2025-03
     窗口 = [2025-01 → 2025-03]
     累计 = 37000

这就是“窗口在时间轴上向后滑动”的真实含义。


七、OVER 和 GROUP BY 的本质区别

很多人会把两者混在一起,这里给一个清晰对照:

维度GROUP BYOVER
是否合并行
是否保留明细
是否能做累计
是否依赖顺序

一句话总结:

GROUP BY 改变结果集结构,OVER 只改变每一行“看到的数据范围”。


八、一个非常实用的变体:滚动统计

如果你把窗口范围改成:

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW

含义立刻变成:

近 3 个月的滚动总额

你会发现:
SQL 完全没变,变的只是“窗口大小”。

这也是窗口函数被称为“分析型 SQL”的原因。


九、最后的总结

关于 OVER,只需要记住三句话:

  1. 它不是用来分组的,而是用来定义“视角”的

  2. ORDER BY 决定时间或逻辑方向

  3. ROWS BETWEEN 决定你能看到多远的历史

当你真正理解了“窗口在滑动”,
累计、排名、同比、环比,本质上都是同一套机制的不同表达。


该文章在 2026/2/11 12:08:02 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved