SQL怎样计算分组内的移动总和_使用ROWS BETWEEN定义窗口

来源:站长工具作者:深圳网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL怎样计算分组内的移动总和_使用ROWS BETWEEN定义窗口》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL怎样计算分组内的移动总和_使用ROWS BETWEEN定义窗口》有用,将其分享出去将是对创作者最好的鼓励。

在SQL的实际业务处理中,经常需要针对某个分组内的数据,按照时间、序号等顺序计算移动总和,比如统计每个用户近3天的消费总额、每个部门连续3个月的业绩累计等。这类需求可以通过窗口函数配合ROWS BETWEEN子句来高效实现,不需要复杂的自连接操作。

SQL怎样计算分组内的移动总和_使用ROWS BETWEEN定义窗口

移动总和与ROWS BETWEEN基础概念

移动总和指的是在有序的数据集合中,针对当前行,取其前后指定范围内的行数据进行计算得到的总和。ROWS BETWEEN是窗口函数中用来定义窗口范围的子句,它明确指定了当前行前后参与计算的行的范围,是控制移动总和计算逻辑的核心部分。

ROWS BETWEEN的语法结构如下:

ROWS BETWEEN 起始边界 AND 结束边界

常见的边界取值包括:

  • UNBOUNDED PRECEDING:窗口起始于分组的第1行
  • N PRECEDING:窗口起始于当前行的前N行
  • CURRENT ROW:窗口包含当前行
  • N FOLLOWING:窗口结束于当前行的后N行
  • UNBOUNDED FOLLOWING:窗口结束于分组的最后1行

分组内移动总和的实现步骤

1. 准备测试数据

我们首先创建一张用户消费记录表,包含用户ID、消费日期和消费金额三个字段,用于演示分组内的移动总和计算:

-- 创建测试表
CREATE TABLE user_consume (
    user_id INT,
    consume_date DATE,
    amount DECIMAL(10,2)
);

-- 插入测试数据
INSERT INTO user_consume VALUES
(1, '2024-01-01', 100.00),
(1, '2024-01-02', 150.00),
(1, '2024-01-03', 200.00),
(1, '2024-01-04', 120.00),
(2, '2024-01-01', 80.00),
(2, '2024-01-02', 90.00),
(2, '2024-01-03', 110.00);

2. 计算分组内从起始到当前行的累计总和

如果需要计算每个用户从第一次消费到当前日期的累计消费总额,窗口范围可以定义为从分组第一行到当前行:

SELECT 
    user_id,
    consume_date,
    amount,
    SUM(amount) OVER (
        PARTITION BY user_id 
        ORDER BY consume_date 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS total_amount
FROM user_consume
ORDER BY user_id, consume_date;

上述查询中,PARTITION BY user_id表示按用户ID分组,ORDER BY consume_date保证组内按消费日期排序,ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW定义了窗口为组内从第一行到当前行的所有数据,最终SUM函数计算这个窗口内的金额总和。

3. 计算分组内近3行的移动总和

如果需要计算每个用户近3次消费的移动总和(包含当前行和前2行),窗口范围可以定义为前2行到当前行:

SELECT 
    user_id,
    consume_date,
    amount,
    SUM(amount) OVER (
        PARTITION BY user_id 
        ORDER BY consume_date 
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS moving_3_total
FROM user_consume
ORDER BY user_id, consume_date;

此时对于用户1的2024-01-01记录,前2行不存在,窗口只有当前行,总和为100;2024-01-02记录,窗口包含前1行和当前行,总和为250;2024-01-03及之后的记录,窗口都包含当前行和前2行,总和为对应三行的金额之和。

不同窗口范围的计算结果对比

我们可以通过一个表格对比不同ROWS BETWEEN配置下的移动总和计算逻辑:

ROWS BETWEEN配置窗口范围说明适用场景
UNBOUNDED PRECEDING AND CURRENT ROW分组第一行到当前行累计总和统计
N PRECEDING AND CURRENT ROW当前行前N行到当前行近N+1条记录的移动总和
CURRENT ROW AND N FOLLOWING当前行到当前行后N行未来N+1条记录的预累计
N PRECEDING AND M FOLLOWING当前行前N行到当前行后M行当前行前后指定范围的移动总和

注意事项

使用ROWS BETWEEN时需要注意几个问题:

  • 如果分组内的行数不足窗口定义的行数,窗口会自动适配存在的行,不会报错,比如前2行不存在时只计算存在的行的总和
  • ORDER BY子句在窗口函数中非常重要,没有排序的话行的顺序是不确定的,移动总和的结果也会不符合预期
  • ROWS是基于行的物理位置计算范围,如果需要按值的范围计算(比如近3天的记录,不管中间有没有缺失日期),需要使用RANGE BETWEEN而不是ROWS BETWEEN

如果需要计算按值范围的移动总和,比如每个用户近3天(按日期差计算)的消费总和,可以参考以下示例:

SELECT 
    user_id,
    consume_date,
    amount,
    SUM(amount) OVER (
        PARTITION BY user_id 
        ORDER BY consume_date 
        RANGE BETWEEN INTERVAL 2 DAY PRECEDING AND CURRENT ROW
    ) AS range_3day_total
FROM user_consume
ORDER BY user_id, consume_date;

这个查询会计算同一个用户中,消费日期在当前日期前2天到当前日期之间的所有消费金额总和,和ROWS按行数计算的逻辑有明显区别。

SQL移动总和ROWS_BETWEEN窗口函数分组计算修改时间:2026-07-03 02:33:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。