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

SQL Server 2012如何实现非负待办作业滚动总计计算

解决方案

不需要使用游标,使用SQL Server 2012支持的递归公共表表达式(CTE)即可实现该逻辑,性能优于游标实现。

你之前使用的普通累加窗口函数无法满足需求的原因是:窗口累加会直接计算全量的总到期数减去总Slots数,无法处理中间步骤出现负数时重置为0的逻辑,而这个重置操作会影响后续所有周的计算结果,必须通过逐行依赖上一步计算结果的逻辑实现。

完整实现代码

-- 测试样例表,可替换为你自己的业务表
DECLARE @TaskTable TABLE (
    Week DATE,
    Slots INT,
    Due INT
);
INSERT INTO @TaskTable
VALUES
('2021-08-23',0,1),
('2021-08-30',2,3),
('2021-09-06',5,2),
('2021-09-13',1,4);

WITH SortedData AS (
    -- 按周排序生成行号,用于递归逐行计算
    SELECT 
        Week, Slots, Due,
        ROW_NUMBER() OVER (ORDER BY Week) AS rn
    FROM @TaskTable
),
RecursiveTotal AS (
    -- 锚点成员:计算第一周的待办总计
    SELECT 
        Week, Slots, Due, rn,
        IIF(Due - Slots > 0, Due - Slots, 0) AS Total
    FROM SortedData
    WHERE rn = 1
    UNION ALL
    -- 递归成员:逐行计算后续每周的待办总计,依赖上一周的计算结果
    SELECT 
        s.Week, s.Slots, s.Due, s.rn,
        IIF(r.Total + s.Due - s.Slots > 0, r.Total + s.Due - s.Slots, 0) AS Total
    FROM SortedData s
    INNER JOIN RecursiveTotal r ON s.rn = r.rn + 1
)
SELECT Week, Slots, Due, Total
FROM RecursiveTotal
ORDER BY rn;

补充说明

  • 如果你的数据行数超过100行,需要在查询末尾添加 OPTION (MAXRECURSION 0) 来解除默认的递归深度限制,0代表无递归深度限制,也可以设置为和你实际最大周数匹配的数值。
  • 如果确实需要使用游标实现,建议使用快进只读游标,这类游标是SQL Server中性能最优的游标类型,适合这种单方向遍历、只读的计算场景,实现逻辑和你给出的JS逻辑完全一致:初始化Total变量为0,逐行遍历按周排序的数据集,依次计算每行的Total值后更新到表中即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:30:01