SQL中如何实现按周统计的滚动平均_窗口函数日期处理

来源:Golang编程网作者:南京SEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL中如何实现按周统计的滚动平均_窗口函数日期处理》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL中如何实现按周统计的滚动平均_窗口函数日期处理》有用,将其分享出去将是对创作者最好的鼓励。

在业务数据分析中,经常需要统计每周的订单量、销售额等指标,同时计算近3周、近4周的滚动平均值来观察趋势变化,这个需求可以通过SQL的日期处理结合窗口函数高效实现。

第一步:实现按周统计基础指标

首先需要把原始数据按周分组,统计每周的目标指标。这里需要先处理日期字段,将日期转换为对应的周标识,不同数据库的日期函数略有差异,以下是常见数据库的实现方式:

MySQL按周统计示例

MySQL中可以使用YEARWEEK()函数获取年和周的组合标识,第一个参数传日期字段,第二个参数传1表示周从周一开始,符合国内常用的周起始规则:

-- 假设有订单表order_table,包含order_date(订单日期)、order_amount(订单金额)字段
SELECT
    YEARWEEK(order_date, 1) AS week_id,  -- 周标识,格式为YYYYWW
    MIN(order_date) AS week_start,       -- 周起始日
    MAX(order_date) AS week_end,         -- 周结束日
    SUM(order_amount) AS week_sales      -- 周销售额
FROM order_table
GROUP BY YEARWEEK(order_date, 1)
ORDER BY week_id;

PostgreSQL按周统计示例

PostgreSQL可以使用DATE_TRUNC()函数直接截断到周维度,得到周的起始日期:

SELECT
    DATE_TRUNC('week', order_date) AS week_start,  -- 周起始日,默认周从周日开始,可通过设置调整
    SUM(order_amount) AS week_sales
FROM order_table
GROUP BY DATE_TRUNC('week', order_date)
ORDER BY week_start;

第二步:用窗口函数计算滚动平均

得到按周统计的结果后,就可以使用窗口函数计算滚动平均值。滚动平均属于典型的滑动窗口计算场景,SQL的AVG()函数结合OVER()子句即可实现,核心是通过ROWSRANGE指定窗口范围。

如果需要计算近3周(包含当前周)的滚动平均,窗口范围可以设置为ROWS BETWEEN 2 PRECEDING AND CURRENT ROW,表示当前行往前2行到当前行的范围:

-- 以上一步的周统计结果作为子查询,计算近3周滚动平均
WITH week_stat AS (
    SELECT
        YEARWEEK(order_date, 1) AS week_id,
        MIN(order_date) AS week_start,
        SUM(order_amount) AS week_sales
    FROM order_table
    GROUP BY YEARWEEK(order_date, 1)
)
SELECT
    week_id,
    week_start,
    week_sales,
    -- 计算近3周滚动平均,不足3周时按实际行数计算
    AVG(week_sales) OVER (
        ORDER BY week_id
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS rolling_3w_avg
FROM week_stat
ORDER BY week_id;

日期处理的注意事项

  • 周起始日设置:不同数据库的周默认起始日不同,MySQL的YEARWEEK()第二个参数可以指定,PostgreSQL可以通过SET datestyle调整,避免周划分不符合业务预期。
  • 跨年周处理:跨年的周标识需要保证排序正确,比如2023年第52周之后是2024年第1周,按周标识排序时不会出现顺序错乱。
  • 缺失周处理:如果某周没有数据,分组后不会出现该周的记录,会导致滚动窗口的行数不对,需要先生成连续的周序列再左关联统计结果,补0处理缺失周。

补充:缺失周补0的完整示例

以下是MySQL中生成连续周序列并补0的完整实现:

-- 生成近12周的连续周序列
WITH RECURSIVE week_series AS (
    SELECT 
        YEARWEEK(DATE_SUB(CURDATE(), INTERVAL 11 WEEK), 1) AS week_id,
        DATE_SUB(CURDATE(), INTERVAL 11 WEEK) AS week_start
    UNION ALL
    SELECT 
        YEARWEEK(DATE_ADD(week_start, INTERVAL 1 WEEK), 1),
        DATE_ADD(week_start, INTERVAL 1 WEEK)
    FROM week_series
    WHERE week_start < CURDATE()
),
-- 原始周统计
week_stat AS (
    SELECT
        YEARWEEK(order_date, 1) AS week_id,
        SUM(order_amount) AS week_sales
    FROM order_table
    WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 11 WEEK)
    GROUP BY YEARWEEK(order_date, 1)
)
-- 关联计算滚动平均
SELECT
    ws.week_id,
    ws.week_start,
    COALESCE(ws2.week_sales, 0) AS week_sales,
    AVG(COALESCE(ws2.week_sales, 0)) OVER (
        ORDER BY ws.week_id
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS rolling_3w_avg
FROM week_series ws
LEFT JOIN week_stat ws2 ON ws.week_id = ws2.week_id
ORDER BY ws.week_id;

SQL窗口函数滚动平均按周统计日期处理修改时间:2026-06-15 02:00:39

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