SQL - Subtracting a depleting value from rows
Left as an exercise to the OP: Figuring out the correct results given the sample data and summarizing the results of the following query:
-- Create some test data.
declare @Pooled_Lots as table ( Id int, Pool int, Lot int, Quantity int );
insert into @Pooled_Lots ( Id, Pool, Lot, Quantity ) values
( 1, 1, 1, 5 ), ( 2, 1, 2, 10 ), ( 3, 1, 3, 4 ),
( 4, 2, 1, 7 ),
( 5, 3, 1, 1 ), ( 6, 3, 2, 5 );
declare @Pool_Consumption as table ( Id int, Pool int, QuantityConsumed int );
insert into @Pool_Consumption ( Id, Pool, QuantityConsumed ) values
( 1, 1, 17 ), ( 2, 2, 8 ), ( 3, 3, 10 );
select * from @Pooled_Lots order by Pool, Lot;
select * from @Pool_Consumption order by Pool;
with Amos as (
-- Start with Lot 1 for each Pool.
select PL.Pool, PL.Lot, PL.Quantity, PC.QuantityConsumed,
case
when PC.QuantityConsumed is NULL then PL.Quantity
when PL.Quantity >= PC.QuantityConsumed then PL.Quantity - PC.QuantityConsumed
when PL.Quantity < PC.QuantityConsumed then 0
end as RunningQuantity,
case
when PC.QuantityConsumed is NULL then 0
when PL.Quantity >= PC.QuantityConsumed then 0
when PL.Quantity < PC.QuantityConsumed then PC.QuantityConsumed - PL.Quantity
end as RemainingDemand
from @Pooled_Lots as PL left outer join
@Pool_Consumption as PC on PC.Pool = PL.Pool
where Lot = 1
union all
-- Add the next Lot for each Pool.
select PL.Pool, PL.Lot, PL.Quantity, CTE.QuantityConsumed,
case
when CTE.RunningQuantity + PL.Quantity >= CTE.RemainingDemand then CTE.RunningQuantity + PL.Quantity - CTE.RemainingDemand
when CTE.RunningQuantity + PL.Quantity < CTE.RemainingDemand then 0
end,
case
when CTE.RunningQuantity + PL.Quantity >= CTE.RemainingDemand then 0
when CTE.RunningQuantity + PL.Quantity < CTE.RemainingDemand then CTE.RemainingDemand - CTE.RunningQuantity - PL.Quantity
end
from Amos as CTE inner join
@Pooled_Lots as PL on PL.Pool = CTE.Pool and PL.Lot = CTE.Lot + 1
)
select *,
case
when Lot = ( select max( Lot ) from @Pooled_Lots where Pool = Amos.Pool ) then RunningQuantity - RemainingDemand
else NULL end as SurplusOrDeficit
from Amos
order by Pool, Lot;