SQL Server实现带50%阈值重置的动态累计求和需求
实现带有重置逻辑的累计求和
要实现你描述的特殊累计求和逻辑(当累计值满足特定条件时重置起始点),我们可以使用递归CTE来逐行处理数据,跟踪当前的累计值和分组起始值,根据条件判断是否需要重置累计。
首先,结合你给出的示例输出,我们可以明确核心逻辑:
- 初始阶段从第一个薪资值开始逐行累加;
- 当累计值达到某个阈值时,后续累计从触发行的薪资值重新开始,与下一行薪资相加作为新的累计起点,之后继续正常累加;
- 再次满足阈值条件时重复上述重置操作。
示例SQL代码
假设你的表名为salary_table,包含ID和Salary两列,以下代码可以精准生成你需要的输出:
WITH RECURSIVE running_calc AS ( -- 初始化第一行数据 SELECT ID, Salary, Salary AS "Running Total", Salary AS group_start FROM salary_table WHERE ID = 1 UNION ALL -- 递归处理后续每一行 SELECT t.ID, t.Salary, -- 根据示例规律判断是否重置:前一个累计值等于当前行与前一行薪资和的2倍时,重置累计 CASE WHEN cte."Running Total" = 2 * ((SELECT Salary FROM salary_table WHERE ID = t.ID - 1) + t.Salary) THEN (SELECT Salary FROM salary_table WHERE ID = t.ID - 1) + t.Salary -- 不满足条件则继续累加 ELSE cte."Running Total" + t.Salary END AS "Running Total", -- 更新分组起始值 CASE WHEN cte."Running Total" = 2 * ((SELECT Salary FROM salary_table WHERE ID = t.ID - 1) + t.Salary) THEN (SELECT Salary FROM salary_table WHERE ID = t.ID - 1) ELSE cte.group_start END AS group_start FROM salary_table t JOIN running_calc cte ON t.ID = cte.ID + 1 ) -- 按ID排序输出结果 SELECT ID, Salary, "Running Total" FROM running_calc ORDER BY ID;
代码说明
- 递归CTE初始化:先获取第一行数据,设置初始累计值为第一个薪资,分组起始值也同步为该值;
- 递归处理逻辑:对每一行数据进行判断:
- 若满足重置条件(前一个累计值等于当前行与前一行薪资和的2倍),则新的累计值为前一行薪资加当前行薪资,同时更新分组起始值为前一行的薪资;
- 若不满足条件,则保持累计值的正常累加,分组起始值不变;
- 结果输出:按ID升序排列,输出最终的ID、薪资和自定义累计值。
灵活调整说明
如果你的实际重置逻辑是累计值比分组起始值高出50%时重置(即累计值 > 分组起始值 × 1.5),可以修改CASE语句中的判断条件为:
WHEN cte."Running Total" + t.Salary > cte.group_start * 1.5 THEN t.Salary -- 从当前薪资重新开始累计 ELSE cte."Running Total" + t.Salary
你可以根据实际业务需求,自由调整条件判断逻辑来适配不同的重置规则。
内容的提问来源于stack exchange,提问作者Gork. O
相关产品推荐
相关产品推荐

