我有两张桌子 - 让我们称之为dbo.ValuesToReduce和dbo.Reserve 第一个表(dbo.ValuesToReduce)中的数据是:
ValuesToReduceId | PartnerId | Value
-------------------------------------
1 | 1 | 53.15
2 | 2 | 601.98
3 | 1 | 91.05
4 | 2 | 44.56
5 | 3 | 19.11
第二个表(dbo.Reserve)看起来像这个
ReserveId | PartnerId | Value
-------------------------------
1 | 1 | -101.55
2 | 2 | -425.19
3 | 3 | -28.17
我需要做的是:使用后一个储备表更新ValuesToReduce表中的值,减少数量直到预留供应耗尽。这是运行脚本后我应该得到的:
ValuesToReduceId | PartnerId | Value
-------------------------------------
1 | 1 | 0.00
2 | 2 | 176.79
3 | 1 | 42.65
4 | 2 | 44.56
5 | 3 | 0.00
ReserveId | PartnerId | Value
-------------------------------
1 | 1 | 0.00
2 | 2 | 0.00
3 | 3 | -9.06
所以基本上,每个伙伴都有一个他可以消耗的“储备”,如果储备中还有东西,价值表中的值应该由合作伙伴相应减少。储备应按ValuesToReduceId提供的顺序并置。
对于PartnerId为1的合作伙伴,您可以看到他有足够的储备来将他的第一个值更新为0,并且还有一些剩下的可以将第二个值减少到该数量。
ID为2的合作伙伴有一个425.19的保留,并且该合作伙伴的值表中有两个条目,601.98和44.56,按顺序(通过ValuesToReduceId),所以我们只更新了第一个值,因为保留是两者都不够大。错误的方法是将第二个值更新为0.00,将第一个值更新为221.35。
ID为3的合作伙伴有足够的储备,因此在将其值更新为0后,他留下了-9.06
我尝试了递归cte的东西,但我似乎无法理解它。 希望我能够清楚地描述这个问题。
答案 0 :(得分:1)
据我所知,你不能在一个select语句中更新两个表。
但是您可以使用WHILE循环在SQL中执行此操作。搜索第一个交易,然后执行,直到没有可能的交易。
declare @valid int
declare @resid int
declare @val float
while 1 = 1
begin
select top 1
@resid = r.ReserveId
, @valid = v.ValuesToReduceId
, @val = CASE WHEN -r.Value > v.Value THEN v.Value ELSE -r.Value END
from ValuesToReduce v
inner join Reserves r on r.PartnerId = v.PartnerId
where r.Value < 0 and v.Value > 0
order by r.ReserveId
if @@rowcount = 0
break
update ValuesToReduce
set Value = Value - @val
where ValuesToReduceId = @valid
update Reserves
set Value = Value + @val
where ReserveId = @resid
end
以下是创建测试表的代码:
create table ValuesToReduce (
ValuesToReduceId int,
PartnerId int,
Value float
)
insert into ValuesToReduce values (1,1,53.15)
insert into ValuesToReduce values (2,2,601.98)
insert into ValuesToReduce values (3,1,91.05)
insert into ValuesToReduce values (4,2,44.56)
insert into ValuesToReduce values (5,3,19.11)
create table Reserves (
ReserveId int,
PartnerId int,
Value float
)
insert into Reserves values (1,1,-101.55)
insert into Reserves values (2,2,-425.19)
insert into Reserves values (3,3,-28.17)