基本上我想要做的是减去某个值,然后按顺序开始播放var1-3中的值
在:
ID|var1|var2|var3
1| 500| 100| 200
2| 800| 400| 300
3|1200|3200|2400
样本1 - 减去600我会得到
ID|var1|var2|var3
1| 0| 0| 200
2| 800| 400| 300
3|1200|3200|2400
样本2 - 减去750我会得到
ID|var1|var2|var3
1| 0| 0| 50
2| 800| 400| 300
3|1200|3200|2400
样本3 - 减去900我会得到
ID|var1|var2|var3
1| 0| 0| 0
2| 700| 400| 300
3|1200|3200|2400
“0”字段可以为“null”。
DECLARE @Amount DECIMAL(18,2) = 900
CREATE TABLE #table(ID [int] NULL, var1 decimal(18,2), var2 decimal(18,2), var3 decimal(18,2))
INSERT INTO #table (ID,var1,var2,var3) VALUES (1,500,100,200)
INSERT INTO #table (ID,var1,var2,var3) VALUES (2,800,400,300)
INSERT INTO #table (ID,var1,var2,var3) VALUES (3,1200,3200,2400)
DECLARE @CurrentRow INT
DECLARE @OrgAmount DECIMAL(18,2)
WHILE (SELECT SUM( ISNULL(var1,0)) + SUM( ISNULL(var2,0)) + SUM( ISNULL(var3,0)) FROM #table) != 0 AND @Amount != 0
BEGIN
SELECT TOP 1 @CurrentRow = ID FROM #table
WHERE var1 != 0 OR var2 != 0 OR var3 != 0
ORDER BY ID ASC
UPDATE #table
SET var1 = CASE WHEN var1 - @Amount < 0 THEN 0 ELSE var1 - @Amount END,
@OrgAmount = var1
WHERE @CurrentRow = ID
SET @Amount = CASE WHEN @Amount - @OrgAmount < 0 THEN 0 ELSE @Amount - @OrgAmount END
UPDATE #table
SET var2 = CASE WHEN var2 - @Amount < 0 THEN 0 ELSE var2 - @Amount END,
@OrgAmount = var2
WHERE @CurrentRow = ID
SET @Amount = CASE WHEN @Amount - @OrgAmount < 0 THEN 0 ELSE @Amount - @OrgAmount END
UPDATE #table
SET var3 = CASE WHEN var3 - @Amount < 0 THEN 0 ELSE var3 - @Amount END,
@OrgAmount = var3
WHERE @CurrentRow = ID
SET @Amount = CASE WHEN @Amount - @OrgAmount < 0 THEN 0 ELSE @Amount - @OrgAmount END
END
SELECT * FROM #table
DROP TABLE #table
感谢您的帮助。
答案 0 :(得分:3)
虽然我同意这些评论,但这可能更好地布局,下面的sql显示了解决问题的方法之一:
declare @subtract int
set @subtract = 900
;WITH CTE_Data as (
select id=1, var1= 500, var2 = 100, var3 = 200
union select id=2, var1= 800, var2 = 400, var3 = 300
union select id=3, var1= 1200, var2 = 3200, var3 = 2400
),
CTE_RunningTotals as (
select
id,
pretot = 0,
var1, var2, var3,
tot1 = var1,
tot2 = var1 + var2,
tot3 = var1 + var2 + var3
from CTE_Data where id = 1
union all
select
d.id,
pretot = rt.tot3,
d.var1, d.var2, d.var3,
tot1 = d.var1 + rt.tot3,
tot2 = d.var1 + d.var2 + rt.tot3,
tot3 = d.var1 + d.var2 + d.var3 + rt.tot3
from
CTE_Data d
join CTE_RunningTotals rt on d.id = rt.id+1
where d.id > 1
)
select
id,
var1 = case when pretot - @subtract >= 0 then var1
else case when tot1 - @subtract > 0 then tot1 - @subtract else 0 end
end,
var2 = case when tot1 - @subtract >= 0 then var2
else case when tot2 - @subtract > 0 then tot2 - @subtract else 0 end
end,
var3 = case when tot2 - @subtract >= 0 then var3
else case when tot3 - @subtract >0 then tot3 - @subtract else 0 end
end
from CTE_RunningTotals
返回
id var1 var2 var3
1 0 0 0
2 700 400 300
3 1200 3200 2400
CTE_Data只是输入数据,您可以为源表更改此项。
CTE_RunningTotals包含原始数据,以及表格中当前行/列的所有值的运行总计。
如果前一行/列为零(即减去的值大于目前的运行总数),则从当前值中取减值,否则返回数据值。
如果您在CTE声明之后select * from CTE_RunningTotals
,您可能会发现更容易找出正在发生的事情,以便您可以看到正常工作。