I want to achieve the below output from the given input tables.
Input Table (Bucket to be filled)
ID | FullCapacity | CurrentAmount
---+--------------+--------------
B1 | 100 | 0
B2 | 50 | 0
B3 | 70 | 0
Input Table (Filler Table)
ID | Filler
---+-------
F1 | 90
F2 | 70
F3 | 40
F4 | 20
Output table should have below showing filling process.
ID | FullCapacity | CurrentAmount
---+--------------+--------------
B1 | 100 | 90
B2 | 50 | 0
B3 | 70 | 0
---+--------------+--------------
B1 | 100 | 100
B2 | 50 | 50
B3 | 70 | 10
---+--------------+--------------
B1 | 100 | 100
B2 | 50 | 50
B3 | 70 | 50
---+--------------+--------------
B1 | 100 | 100
B2 | 50 | 50
B3 | 70 | 70
I am trying to fill this one by one from filler to bucket. Can we do this without using cursor?
Please see that we can have multiple types of buckets for example red bucket, blue bucket and red filler, blue filler. Red filler to go to red bucket, blue filler to blue and so on.
Thank you
You can do this in SQL Server 2008 like this:
declare @Buckets table (ID char(2), FullCapacity int)
declare @Filler table (ID char(2), Filler int)
insert into @Buckets
select 'B1', 100 union all
select 'B2', 50 union all
select 'B3', 70
insert into @Filler
select 'F1', 90 union all
select 'F2', 70 union all
select 'F3', 40 union all
select 'F4', 20
select
b.ID,
b.FullCapacity,
case
when f.TotalFill < b.RunningTotalCapacity then 0
when f.TotalFill > b.RunningTotalCapacity + b.FullCapacity then b.FullCapacity
else f.TotalFill - b.RunningTotalCapacity
end as CurrentAmount
from
(
select
ID,
Filler,
(
select sum(f2.Filler)
from @Filler as f2
where f2.ID <= f.ID
) as TotalFill
from @Filler as f
) as f
cross join
(
select
ID,
FullCapacity,
(
select isnull(sum(b2.FullCapacity), 0)
from @Buckets as b2
where b2.ID < b.ID
) as RunningTotalCapacity
from @Buckets as b
) as b
order by f.ID, b.ID
You can do this using windowing functions like this:
declare @Buckets table (ID char(2), FullCapacity int)
declare @Filler table (ID char(2), Filler int)
insert into @Buckets values
('B1', 100),
('B2', 50),
('B3', 70)
insert into @Filler values
('F1', 90),
('F2', 70),
('F3', 40),
('F4', 20)
;with fillerCte as
(
select
ID,
Filler,
sum(Filler) over (order by ID) as TotalFill
from @Filler
),
BucketCte as
(
select
ID,
FullCapacity,
sum(FullCapacity) over (order by ID) - FullCapacity as RunningTotalCapacity
from @Buckets
)
select
b.ID,
b.FullCapacity,
case
when f.TotalFill < b.RunningTotalCapacity then 0
when f.TotalFill > b.RunningTotalCapacity + b.FullCapacity then b.FullCapacity
else f.TotalFill - b.RunningTotalCapacity
end as CurrentAmount
from fillerCte as f
cross join BucketCte as b
order by f.ID, b.ID