我试图在没有游标的情况下进行以下操作。有可能吗?
我有这个变量:
DECLARE @Amount MONEY = 800;
我目前的样本表:
EntryID Amount
--------------------------------------------
1 200
2 250
3 600
4 100
... ....(could be many more rows)
我希望能够更新表格,只显示" Amount"它需要加起来@Amount变量($ 800)。所以我希望桌子能像这样结束:
EntryID Amount
--------------------------------------------
1 200 (uses up full 200)
2 250 (uses up full 250)
3 350 (uses up 350 of the 600)
或者就像这样
EntryID Amount Distrib
--------------------------------------------
1 200 200
2 250 250
3 600 350
4 100 0
... ... ...
因此SUM()
等于@Amount
提前致谢!
PS - 我在SQL Server 2012中这样做
更新
这是我的最终解决方案。再次感谢,戈登:
DECLARE @Amount money = 800;
DECLARE @tmpPaymentDist TABLE (EntryID INT, Amount MONEY, Distrib MONEY);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (1, 200);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (2, 250);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (3, 600);
INSERT INTO @tmpPaymentDist (EntryID, Amount) VALUES (4, 100);
with toupdate as (
select t.*,
(case when sum(amount) over (order by entryid) <= @amount
then amount
when sum(amount) over (order by entryid) < @amount + amount
then @amount - (sum(amount) over (order by entryid) - amount)
else 0
end) as new_distrib
from @tmpPaymentDist t
)
update T set distrib = new_distrib
FROM @tmpPaymentDist T
INNER JOIN toupdate T2 ON T2.EntryID = T.EntryID
WHERE T2.new_distrib > 0
SELECT * FROM @tmpPaymentDist
答案 0 :(得分:3)
是的,你可以使用累积总和而无需游标:
select t.*,
(case when sum(amount) over (order by entryid) <= @amount
then amount
when sum(amount) over (order by entryid) < @amount + amount
then @amount - (sum(amount) over (order by entryid) - amount)
else 0
end) as distrib
from table t;
即,使用累计金额进行计算。
对于update
,您可以使用相同的逻辑:
with toupdate as (
select t.*,
(case when sum(amount) over (order by entryid) <= @amount
then amount
when sum(amount) over (order by entryid) < @amount + amount
then @amount - (sum(amount) over (order by entryid) - amount)
else 0
end) as new_distrib
from table t
)
update toudpate
set distrib = new_distrib;