SQL Server 18.11.1:满足特定条件时重启滚动求和的实现求助
解决SQL Server中带重启条件的滚动求和问题
这类带动态重启规则的滚动计算无法通过普通窗口函数实现,必须通过递归CTE逐行判断条件并构建分组。以下是针对你的需求的完整解决方案:
测试数据准备(可选)
如果已有数据表,可跳过此步骤:
CREATE TABLE #TestData ( ID INT PRIMARY KEY, Value INT, Counters INT ); INSERT INTO #TestData (ID, Value, Counters) VALUES (1,6,1),(2,1,1),(3,1,1),(4,4,1),(5,5,1), (6,6,1),(7,7,1),(8,8,1),(9,9,1),(10,10,1), (11,1,1),(12,1,1),(13,1,1),(14,1,1),(15,3,1);
递归CTE实现滚动求和
WITH RecursiveRolling AS ( -- 锚点:初始化第一行数据 SELECT ID, Value, Rolling_Sum = Value, Rolling_Counter_Sum = Counters, GroupID = 1 FROM #TestData WHERE ID = 1 UNION ALL -- 递归处理后续每一行 SELECT td.ID, td.Value, -- 判断是否重置滚动和 CASE WHEN rr.Rolling_Sum + td.Value >= 10 OR rr.Rolling_Counter_Sum + td.Counters > 3 THEN td.Value ELSE rr.Rolling_Sum + td.Value END AS Rolling_Sum, -- 判断是否重置累计计数 CASE WHEN rr.Rolling_Sum + td.Value >= 10 OR rr.Rolling_Counter_Sum + td.Counters > 3 THEN td.Counters ELSE rr.Rolling_Counter_Sum + td.Counters END AS Rolling_Counter_Sum, -- 更新分组ID:触发条件时新建分组 CASE WHEN rr.Rolling_Sum + td.Value >= 10 OR rr.Rolling_Counter_Sum + td.Counters > 3 THEN rr.GroupID + 1 ELSE rr.GroupID END AS GroupID FROM #TestData td INNER JOIN RecursiveRolling rr ON td.ID = rr.ID + 1 ) SELECT Value, Rolling_Sum, -- 格式化触发提示,与预期结果对齐 CASE WHEN Rolling_Sum >= 10 THEN CONVERT(VARCHAR, Rolling_Counter_Sum) + ' --触发重启' WHEN Rolling_Counter_Sum = 3 THEN CONVERT(VARCHAR, Rolling_Counter_Sum) + ' --触发重启' ELSE CONVERT(VARCHAR, Rolling_Counter_Sum) END AS Rolling_Counter_Sum FROM RecursiveRolling ORDER BY ID; -- 清理临时表 DROP TABLE #TestData;
逻辑说明
- 锚点成员:选取ID最小的记录作为第一个分组的起点,初始化滚动和、累计计数及分组ID。
- 递归成员:逐行关联上一条记录,检查两个触发条件:
- 累计滚动和加上当前值≥10
- 累计计数加上当前Counters>3
满足任一条件则重置滚动计算(当前值作为新的滚动和起始,计数重置为当前Counters),并创建新分组;否则继续累加。
- 最终查询通过CASE语句添加触发提示,完全匹配你给出的预期输出格式。
内容的提问来源于stack exchange,提问作者Pavels Paukovs
相关产品推荐
相关产品推荐

