You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写MySQL查询计算年初至今累计平均值并每年重置

解决年初至今累计平均值(每年重置)的MySQL查询方案

没问题,我来帮你搞定这个累计平均值的需求~首先我先假设你的表结构包含日期字段(比如record_date)和需要计算平均值的数值字段(比如metric_value)——要是你实际字段名不一样,直接替换成自己的就行。

核心思路

我们需要实现两个关键逻辑:

  1. 按年份分区计算:确保每年的累计平均值独立计算,不会和其他年份的数据混淆;
  2. 1月1日重置为0:对每年1月1日的记录,强制将平均值设为0,之后的记录从年初开始累计计算平均值。

最终查询语句

SELECT
    record_date,
    metric_value,
    -- 处理1月1日重置为0的逻辑,其余日期计算年初至今累计平均
    CASE
        WHEN DAYOFYEAR(record_date) = 1 THEN 0
        ELSE AVG(metric_value) OVER (
            PARTITION BY YEAR(record_date)  -- 按年份分区,每年独立计算
            ORDER BY record_date             -- 按日期排序,保证累计顺序
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  -- 窗口范围:年初到当前行
        )
    END AS average
FROM your_table_name  -- 替换成你的实际表名
ORDER BY record_date;

语句细节解释

  • PARTITION BY YEAR(record_date):把数据按年份拆分成独立的组,这样2023年的累计计算不会包含2024年的数据,完美实现每年重置的效果;
  • ORDER BY record_date:在每个年份组内按日期排序,确保累计计算是从年初到当前行的顺序;
  • ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:明确指定窗口范围是当前年份的第一条记录到当前行,这其实是AVG()窗口函数的默认行为,但写上更直观易懂;
  • CASE语句:通过DAYOFYEAR(record_date) = 1判断是否是当年1月1日,若是则将average设为0,符合你要求的重置规则。

额外补充

  • 如果你的日期字段是DATETIME类型,只需把record_date换成DATE(record_date)即可,不影响分组和计算;
  • 如果数值字段可能存在NULL值,AVG()会自动忽略这些值。要是你需要把NULL当作0来计算,可以把metric_value替换成COALESCE(metric_value, 0);
  • 要是你希望1月1日的记录显示当天的平均值(而不是0),直接去掉CASE语句,保留AVG(metric_value) OVER (...) AS average即可。

内容的提问来源于stack exchange,提问作者Robson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:04:43