I am trying to extend the below query to allow the bucket filling from a table rather than a single value. In below example I want to replace @AmountToAllocate with a table of potential values that will be used to fill the bucket. Any suggestion highly appreciated.
create table dbo.Buckets
( TotalSize int not null,
Amount int not null,
BucketID int not null,
constraint pk_Buckets primary key (BucketID),
constraint ck_Buckets_Amount check ( Amount between 0 and TotalSize)
)
go
insert into dbo.Buckets (TotalSize,Amount,BucketID)
select 10, 1, 1
go
insert into dbo.Buckets (TotalSize,Amount,BucketID)
select 5, 2, 2
go
insert into dbo.Buckets (TotalSize,Amount,BucketID)
select 10, 0, 3
go
insert into dbo.Buckets (TotalSize,Amount,BucketID)
select 10, 0, 4
go
DECLARE @AmountToAllocate INT = 12
;WITH Calculator AS (
SELECT
BucketID, TotalSize, Amount,
AmountLeftToAllocate = CASE
WHEN @AmountToAllocate > (TotalSize - Amount) THEN @AmountToAllocate - (TotalSize - Amount)
WHEN @AmountToAllocate < 0 AND ABS(@AmountToAllocate) > Amount THEN Amount + @AmountToAllocate
ELSE 0 END,
NewAmount = CASE
WHEN @AmountToAllocate > (TotalSize - Amount) THEN TotalSize
WHEN @AmountToAllocate < 0 AND ABS(@AmountToAllocate) > Amount THEN 0
ELSE Amount + @AmountToAllocate END
FROM dbo.Buckets
WHERE BucketID = 1
UNION ALL
SELECT
tr.BucketID, tr.TotalSize, tr.Amount,
AmountLeftToAllocate = CASE
WHEN lr.AmountLeftToAllocate > (tr.TotalSize - tr.Amount) THEN lr.AmountLeftToAllocate - (tr.TotalSize - tr.Amount)
WHEN lr.AmountLeftToAllocate < 0 AND ABS(lr.AmountLeftToAllocate) > tr.Amount THEN tr.Amount + lr.AmountLeftToAllocate
ELSE 0 END,
NewAmount = CASE
WHEN lr.AmountLeftToAllocate > (tr.TotalSize - tr.Amount) THEN tr.TotalSize
WHEN lr.AmountLeftToAllocate < 0 AND ABS(lr.AmountLeftToAllocate) > tr.Amount THEN 0
ELSE tr.Amount + lr.AmountLeftToAllocate END
FROM dbo.Buckets tr
INNER JOIN Calculator lr ON lr.BucketID + 1 = tr.BucketID
)
SELECT
BucketID,
TotalSize,
Amount = NewAmount,
OldAmount = Amount
FROM Calculator