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

TSQL计算滚动累计总额:跨时段累加需求及实现问询

看起来你在计算跨时间段滚动累计时踩了窗口函数分区的坑——你的PARTITION BY里包含了MonthNumber,这会让每个月份的数据单独成组,自然没法实现跨月份的累计。我们来一步步解决这个问题:

需求拆解

你提到的示例逻辑是:

  • 1月Expense+Indemnity总额≈31.7k
  • 2月两类总额≈4.1k,累计后≈35.9k

所以我们需要分两种场景处理:要么按费用类型单独计算累计,要么先汇总月度总额再计算整体累计。


解决方案1:按CostType单独计算滚动累计

如果你需要每个费用类型(Expense/Indemnity)各自的滚动累计值,直接调整窗口函数的分区和排序规则即可:

CREATE TABLE #temptable ( 
    Catastrophe VARCHAR (60), 
    Type VARCHAR (256), 
    CostType VARCHAR (256), 
    FirstLossDate DATE, 
    MonthNumber INT, 
    Amount DECIMAL (38, 6) 
);

INSERT INTO #temptable ( Catastrophe, Type, CostType, FirstLossDate, MonthNumber, Amount) 
VALUES 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 1, 13460.320000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 1, 18314.610000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 2, -1589.340000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 2, 5750.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 3, -2981.250000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 3, -10000.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 4, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 4, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 5, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 5, 0.000000);

-- 分CostType的滚动累计
SELECT 
    Catastrophe, 
    Type, 
    CostType, 
    FirstLossDate, 
    MonthNumber, 
    Amount,
    -- 关键:PARTITION BY不包含MonthNumber,按费用类型分组,按月份排序
    SUM(Amount) OVER (
        PARTITION BY Catastrophe, Type, CostType 
        ORDER BY MonthNumber 
        ROWS UNBOUNDED PRECEDING
    ) AS CostType_RunningTotal
FROM #temptable 
ORDER BY Catastrophe, Type, CostType, MonthNumber;

DROP TABLE #temptable;

结果中CostType_RunningTotal会展示每个费用类型从第1个月到当前月的累计值,比如Expense类型:

  • Month1: 13460.32
  • Month2: 13460.32 - 1589.34 = 11870.98
  • Month3: 11870.98 - 2981.25 = 8889.73

解决方案2:按月度汇总所有CostType后计算总额累计

如果你需要的是每个月份所有费用类型的总额,再计算整体累计(也就是你示例里的31.7k→35.9k逻辑),可以先汇总月度总额,再做累计:

CREATE TABLE #temptable ( 
    Catastrophe VARCHAR (60), 
    Type VARCHAR (256), 
    CostType VARCHAR (256), 
    FirstLossDate DATE, 
    MonthNumber INT, 
    Amount DECIMAL (38, 6) 
);

INSERT INTO #temptable ( Catastrophe, Type, CostType, FirstLossDate, MonthNumber, Amount) 
VALUES 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 1, 13460.320000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 1, 18314.610000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 2, -1589.340000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 2, 5750.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 3, -2981.250000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 3, -10000.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 4, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 4, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Expense - A&O', N'2007-09-13', 5, 0.000000), 
('Hurricane Humberto', 'Reserve', 'Indemnity', N'2007-09-13', 5, 0.000000);

-- 先汇总月度总额,再计算整体累计
WITH MonthlyTotals AS (
    SELECT 
        Catastrophe, 
        Type, 
        FirstLossDate, 
        MonthNumber,
        SUM(Amount) AS MonthlyTotal
    FROM #temptable
    GROUP BY Catastrophe, Type, FirstLossDate, MonthNumber
)
SELECT 
    Catastrophe, 
    Type, 
    FirstLossDate, 
    MonthNumber,
    MonthlyTotal,
    SUM(MonthlyTotal) OVER (
        PARTITION BY Catastrophe, Type 
        ORDER BY MonthNumber 
        ROWS UNBOUNDED PRECEDING
    ) AS Overall_RunningTotal
FROM MonthlyTotals
ORDER BY Catastrophe, Type, MonthNumber;

DROP TABLE #temptable;

这个查询的结果完全匹配你的示例逻辑:

  • Month1: MonthlyTotal=31774.93,Overall_RunningTotal=31774.93
  • Month2: MonthlyTotal=4160.66,Overall_RunningTotal=31774.93+4160.66=35935.59
  • Month3: MonthlyTotal=-12981.25,Overall_RunningTotal=35935.59-12981.25=22954.34

为什么你的原代码没生效?

你的原查询中,PARTITION BY Catastrophe, MonthNumber, Type把每个月份的数据单独分成了一个分区,导致SUM(Amount)只会计算当前月份内的金额,无法跨月份累加。去掉PARTITION里的MonthNumber,才能让窗口函数覆盖从第一个月份到当前月份的所有数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:04:33