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:
- Easy to read
- As few lines as possible
- Runs efficiently
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)
2条答案
按热度按时间bvhaajcl1#
This is the solution using recursive cte
db<>fiddle demo
Note : I get slight different result, you might want to verify the result and the formula for calculation
juud5qan2#
Ok, just go classic with the average:
and since you like clarity, from version 2022 you can DRY the window: