[英]SQL Subtract Variable From Rows
基本上我想做的是从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
谢谢你的帮助。
虽然我同意这些意见,但也许可以更好地进行规划,但以下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
以便您可以看到正常工作,您可能会发现更容易弄清楚发生了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.