I want to calculate the MAUC of items in the future. Items can be components or products created from those components. For every item I gathered a list of all planned supply (e.g. purchase orders) and demand transactions (e.g. sales orders) with their corresponding date. For supply I have a supply price and for demand I set the column to 0.
An example of the above described data can be seen in the columns Item_ID, Date, Quantity and Unit_Value (Below is the code). I simplified the date, because an int fulfills the same purpose as a date when it comes to ordering.
The other three columns (MAUC, Total and Stock) are the columns I want to calculate. Stock is easy with a running sum. The Total too is easy since it is MAUC*Stock=Total. Only the MAUC is difficult.
Why? Because I don't want to use a while
loop over the table and insert every line one by one.
Instead I am looking for a solution that uses over
with aggregate and window functions.
I believe that this would be way faster than a loop.
So my goal is something like this:
Select
Item_ID
, Date
, Quantity
, Unit_Value
, sum(Unit_Value)
over (
Partition by Item
Order by Date
Magic with between current row and unbound preceeding
) as MAUC
From Table
Do you know a solution that fulfills the following criteria:
The last one is the most important to me.
Here is the example code:
Create Table #test (
Item_ID Int
, Date Int
, Quantity Bigint
, Unit_Value Decimal(10,3)
, MAUC float
, Total float
, Stock Bigint
)
Insert Into #test
values
(1,1,10,100,100,1000,10)
, (1,2,-5,0,100,500,5)
, (1,3,-3,0,100,200,2)
, (1,4,20,120,118.181818181818,2600,22)
, (1,5,-5,0,118.181818181818,2009.09090909091,17)
, (1,6,-5,0,118.181818181818,1418.18181818182,12)
, (1,7,-5,0,118.181818181818,827.272727272727,7)
, (1,8,10,90,101.604278074866,1727.27272727273,17)
, (1,9,-2,0,101.604278074866,1524.06417112299,15)
, (1,10,-1,0,101.604278074866,1422.45989304813,14)
, (2,1,100,3,3,300,100)
, (2,2,-30,0,3,210,70)
, (2,3,-60,0,3,30,10)
, (2,4,300,2.5,2.51612903225806,780,310)
, (2,5,-100,0,2.51612903225806,528.387096774194,210)
, (2,6,-150,0,2.51612903225806,150.967741935484,60)
, (2,7,200,3.2,3.04218362282878,790.967741935484,260)
, (2,8,-30,0,3.04218362282878,699.70223325062,230)
, (2,9,-15,0,3.04218362282878,654.069478908189,215)
, (2,10,-70,0,3.04218362282878,441.116625310174,145)
This is the solution using recursive cte
with
rcte as
(
select item_ID, [Date], Quantity, Unit_Value, MAUC, Total, Stock,
calc_mauc = convert(float, Unit_Value)
from #test
where [Date] = 1
union all
select t.item_ID, t.[Date], t.Quantity, t.Unit_Value, t.MAUC, t.Total, t.Stock,
calc_mauc = case when t.Quantity > 0
then convert(float, ((t.Quantity * t.Unit_Value) + r.Total)
/ nullif(r.Stock + t.Quantity, 0))
else r.calc_mauc
end
from #test t
inner join rcte r on t.item_ID = r.item_ID
and t.[Date] = r.[Date] + 1
)
select *
from rcte
order by item_ID, Date
Note : I get slight different result, you might want to verify the result and the formula for calculation