基于上行结果计算单位值:Temp表SQL逻辑实现求助
实现递推计算D列的SQL方案
这是个典型的递推依赖场景——D列的取值完全依赖前一行的计算结果,普通SQL查询没法直接搞定,得用递归CTE(公共表表达式)来实现。我给你针对这个场景写了完整的可运行方案:
第一步:准备测试数据(可选,用来验证)
先创建你的Temp表并插入示例数据:
CREATE TABLE Temp ( S INT PRIMARY KEY, A INT, B INT, C INT ); INSERT INTO Temp VALUES (1, 10, 6, 0), (2, 25, 7, 10), (3, 5, 11, 35), (4, 10, 8, 30);
第二步:递归CTE实现递推计算
核心逻辑分两部分:锚点成员处理首行,递归成员循环计算后续行:
WITH RecursiveTemp AS ( -- 锚点:第一行的D直接等于B列值,转成小数避免精度丢失 SELECT S, A, B, C, CAST(B AS DECIMAL(10,2)) AS D FROM Temp WHERE S = 1 UNION ALL -- 递归:用前一行的D值计算当前行的D SELECT t.S, t.A, t.B, t.C, CAST(((t.A * t.B) + (t.C * rt.D)) / (t.A + t.C) AS DECIMAL(10,2)) AS D FROM Temp t JOIN RecursiveTemp rt ON t.S = rt.S + 1 ) -- 输出最终结果 SELECT * FROM RecursiveTemp;
关键说明
- 锚点成员:专门处理第一行,因为它没有前一行,直接把B列的值赋值给D,这里用
CAST转成DECIMAL(10,2)是为了避免整数除法导致的精度损失。 - 递归成员:通过
JOIN RecursiveTemp rt ON t.S = rt.S + 1关联到上一行的计算结果,严格按照你给出的公式计算当前行的D,同样保留两位小数。 - 行连续性:这个方案依赖
S列是连续递增的整数(就像你的示例数据一样)。如果S不是连续的,你可以先给表加个行编号(用ROW_NUMBER()窗口函数),再基于编号做递推。
运行这个查询后,你就能得到和示例里完全一致的D列结果啦!
内容的提问来源于stack exchange,提问作者Naveen Kumar AMUJURI
相关产品推荐
相关产品推荐

