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

SQL如何计算指定范围记录的近12个月累计和(存在缺失月份场景)

问题根因

你之前的实现用了ROWS滑动窗口,是按物理行数统计往前12条记录的和,完全不考虑月份的连续性,缺月份时会出现统计范围超出12个月、或者包含不符合时间要求的旧数据的问题。

解决方案

分两种实现方式,适配不同的数据库支持情况:

方案1:RANGE滑动窗口(适用支持数值范围RANGE的数据库,如PostgreSQL、Spark SQL、Hive、SQL Server 2022+、MySQL 8.0.28+)

先将int类型的yearmonth转换为总月份数,直接按月份的数值范围滑动窗口,自动过滤不在12个月区间内的记录,不需要补全缺失月份:

WITH month_convert AS (
    SELECT
        tax,
        number,
        yearmonth,
        -- 将YYYYMM格式的int转为总月份数,方便计算月份差
        (yearmonth / 100) * 12 + (yearmonth % 100) AS total_month
    FROM 你的表名
)
SELECT
    number,
    yearmonth,
    SUM(tax) OVER (
        PARTITION BY number
        ORDER BY total_month
        -- 按总月份数的范围滑动,取当前月+往前11个月,共12个月的所有记录
        RANGE BETWEEN 11 PRECEDING AND CURRENT ROW
    ) AS last_12_month_tax_sum
FROM month_convert

如果你的需求是统计当前月份对应的上一个完整自然年的和(比如202105对应2020全年),只需要调整窗口的范围判断即可,把RANGE部分替换为对应时间区间的过滤逻辑。

方案2:自关联计算(兼容所有支持标准SQL的数据库)

如果你的数据库不支持RANGE数值范围滑动,用自关联的方式逐行匹配符合时间范围的记录做聚合:

SELECT
    a.number,
    a.yearmonth,
    SUM(COALESCE(b.tax, 0)) AS last_12_month_tax_sum
FROM 你的表名 a
LEFT JOIN 你的表名 b
    ON a.number = b.number
    -- 判断b表的月份是否落在a表当前行的近12个月区间内
    AND (b.yearmonth / 100) * 12 + (b.yearmonth % 100) 
        BETWEEN (a.yearmonth / 100) * 12 + (a.yearmonth % 100) - 11 
        AND (a.yearmonth / 100) * 12 + (a.yearmonth % 100)
GROUP BY a.number, a.yearmonth
ORDER BY a.number, a.yearmonth

示例验证

以你提供的测试数据为例,number=45、yearmonth=202105的行,近12个月的统计范围是202006~202105,符合条件的tax为100、2、35、47,总和为184,202005的记录因为超出时间范围不会被计入,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:57:02