Author |
Topic |
tempus
Starting Member
47 Posts |
Posted - 2012-03-16 : 03:01:59
|
hello, i am having trouble to calculate a value . having the following table: declare @temptable TABLE ( [product] nvarchar (35), [q jan 2011] numeric (10,4), [jan 2011] numeric (10,4), [q feb 2011] numeric (10,4), [feb 2011] numeric (10,4) , [q mar 2011] numeric (10,4), [mar 2011] numeric (10,4), [q apr 2011] numeric (10,4), [apr 2011] numeric (10,4), [q may 2011] numeric (10,4), [may 2011] numeric (10,4), [q jun 2011] numeric (10,4), [jun 2011] numeric (10,4), [q jul 2011] numeric (10,4), [jul 2011] numeric (10,4), [q aug 2011] numeric (10,4), [aug 2011] numeric (10,4), [q sept 2011] numeric (10,4), [sept 2011] numeric (10,4), [q oct 2011] numeric (10,4), [oct 2011] numeric (10,4), [q nov 2011] numeric (10,4), [nov 2011] numeric (10,4), [q dec 2011] numeric (10,4), [dec 2011] numeric (10,4), [q jan 2012] numeric (10,4), [jan 2012] numeric (10,4), [q feb 2012] numeric (10,4), [feb 2012] numeric (10,4), [sales feb 2012] numeric (10,4), [end of feb 2012 stock] numeric (10,4) ) insert into @temptable select 'PF10100',95.8,7.0989,476.7,6.9892,985,6.9947,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1092.3,8.5255,1000,1455.1the first field on the month represents the quantity, the second is cost per kg. taking into consideration the [end of feb 2012 stock] i need to know at what value is [sales feb 2012].so i have to make a difference from ending stock starting with the last month, until i reach 0. Then i need to calculated the remaining of the month + the previous months until i reach the value of the quantity sold. The result must be an average cost of the months for the quantity sold. Manualy the process looks like this :1455.1 - 1092.3 = 362.8we still have to check back362.8 - 985 = -622.2so this mean that the sales start from 622.2 back , with the cost of 6.99471000-622.2 = 377.8 with the cost of 6.9892the result i need is (622.2*6.9947)+(377.8*6.9892) / 622.2+377.8this means that the 1000 kg sold were at the average cost of 6.9926the table contains multiple products, and values can exists in different months. I apreciate the help and the time given to solve this in advance, Best regards.B. |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-16 : 04:40:05
|
Will this do?declare @temptable TABLE( [product] nvarchar (35),[q jan 2011] numeric (10,4), [jan 2011] numeric (10,4),[q feb 2011] numeric (10,4), [feb 2011] numeric (10,4) , [q mar 2011] numeric (10,4), [mar 2011] numeric (10,4),[q apr 2011] numeric (10,4), [apr 2011] numeric (10,4),[q may 2011] numeric (10,4), [may 2011] numeric (10,4), [q jun 2011] numeric (10,4), [jun 2011] numeric (10,4),[q jul 2011] numeric (10,4), [jul 2011] numeric (10,4),[q aug 2011] numeric (10,4), [aug 2011] numeric (10,4),[q sept 2011] numeric (10,4), [sept 2011] numeric (10,4),[q oct 2011] numeric (10,4), [oct 2011] numeric (10,4),[q nov 2011] numeric (10,4), [nov 2011] numeric (10,4),[q dec 2011] numeric (10,4), [dec 2011] numeric (10,4),[q jan 2012] numeric (10,4), [jan 2012] numeric (10,4),[q feb 2012] numeric (10,4), [feb 2012] numeric (10,4),[sales feb 2012] numeric (10,4), [end of feb 2012 stock] numeric (10,4) )insert into @temptable select 'PF10100',95.8,7.0989,476.7,6.9892,985,6.9947,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1092.3,8.5255,1000,1455.1/* Solution by SwePeso*/-- Create a normalized staging tableCREATE TABLE #Temp ( Product NVARCHAR(35) NOT NULL, SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the staging tableINSERT #Temp ( Product, SeqID, Quantity, Cost )SELECT Product, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT Product, CAST('20110101' AS DATETIME) AS thePeriod, [q jan 2011] AS Quantity, [jan 2011] AS Cost FROM @TempTable UNION ALL SELECT Product, '20110201', [q feb 2011], [feb 2011] FROM @TempTable UNION ALL SELECT Product, '20110301', [q mar 2011], [mar 2011] FROM @TempTable UNION ALL SELECT Product, '20110401', [q apr 2011], [apr 2011] FROM @TempTable UNION ALL SELECT Product, '20110501', [q may 2011], [may 2011] FROM @TempTable UNION ALL SELECT Product, '20110601', [q jun 2011], [jun 2011] FROM @TempTable UNION ALL SELECT Product, '20110701', [q jul 2011], [jul 2011] FROM @TempTable UNION ALL SELECT Product, '20110801', [q aug 2011], [aug 2011] FROM @TempTable UNION ALL SELECT Product, '20110901', [q sept 2011], [sept 2011] FROM @TempTable UNION ALL SELECT Product, '20111001', [q oct 2011], [oct 2011] FROM @TempTable UNION ALL SELECT Product, '20111101', [q nov 2011], [nov 2011] FROM @TempTable UNION ALL SELECT Product, '20111201', [q dec 2011], [dec 2011] FROM @TempTable UNION ALL SELECT Product, '20120101', [q jan 2012], [jan 2012] FROM @TempTable UNION ALL SELECT Product, '20120201', [q feb 2012], [feb 2012] FROM @TempTable UNION ALL SELECT Product, '99991101', [end of feb 2012 stock], 0 FROM @TempTable UNION ALL SELECT Product, '99991201', [sales feb 2012], 0 FROM @TempTable ) AS dWHERE Quantity IS NOT NULL-- Create a staging table for iterationCREATE TABLE #Iteration ( Product NVARCHAR(35), SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the iteration table with an initial value for each productINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT Product, SeqID, Quantity, CostFROM #TempWHERE SeqID = 1-- Iterate until all products has a zero or a negative quantity valueWHILE EXISTS(SELECT * FROM #Iteration WHERE Quantity > 0) UPDATE i SET i.SeqID = t.SeqID, i.Quantity = i.Quantity - t.Quantity, i.Cost = t.Cost FROM #Iteration AS i INNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = i.SeqID + 1 WHERE i.Quantity > 0-- Set all negative values to a positive valueUPDATE #IterationSET Quantity = ABS(Quantity)WHERE Quantity < 0-- Insert a new row for each product with previous last known costINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT t.Product, t.SeqID, t.Quantity - i.Quantity AS Quantity, w.CostFROM #Iteration AS iINNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = 0INNER JOIN #Temp AS w ON w.Product = i.Product AND w.SeqID = i.SeqID + 1-- Display the final resultSELECT Product, SUM(Quantity) AS Total, SUM(Quantity * Cost) / SUM(Quantity) AS AverageFROM #IterationGROUP BY ProductORDER BY Product-- Clean upDROP TABLE #Temp, #Iteration N 56°04'39.26"E 12°55'05.63" |
 |
|
tempus
Starting Member
47 Posts |
Posted - 2012-03-16 : 11:06:14
|
Dear SwePeso , thank you first for the time taken to solve my issue. For one product with those tables i get the correct result buti get an infinite loop at this section when i move to my table ( for february 2011 i have 366 products / lines ):WHILE EXISTS(SELECT * FROM #Iteration WHERE Quantity > 0) UPDATE i SET i.SeqID = t.SeqID, i.Quantity = i.Quantity - t.Quantity, i.Cost = t.Cost FROM #Iteration AS i INNER JOIN #Temp AS t ON t.[cod produs] = i.[cod produs] AND t.SeqID = i.SeqID + 1 WHERE i.Quantity > 0ive let the query to run for 2 and a half hours but with no luck :) .what i did, was to replace some field in your query with my real table ones. what could be the issue here? Thanks in advance, B. |
 |
|
Peso
Starting Member
1 Post |
Posted - 2012-03-16 : 13:56:58
|
It's probably due to there are some Products which have no more rows to deduct and Quantity is still > 0.Add " AND @@ROWCOUNT > 0 " to the IF EXISTS clause. |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-16 : 15:03:36
|
[code]declare @temptable TABLE( [product] nvarchar (35),[q jan 2011] numeric (10,4), [jan 2011] numeric (10,4),[q feb 2011] numeric (10,4), [feb 2011] numeric (10,4) , [q mar 2011] numeric (10,4), [mar 2011] numeric (10,4),[q apr 2011] numeric (10,4), [apr 2011] numeric (10,4),[q may 2011] numeric (10,4), [may 2011] numeric (10,4), [q jun 2011] numeric (10,4), [jun 2011] numeric (10,4),[q jul 2011] numeric (10,4), [jul 2011] numeric (10,4),[q aug 2011] numeric (10,4), [aug 2011] numeric (10,4),[q sept 2011] numeric (10,4), [sept 2011] numeric (10,4),[q oct 2011] numeric (10,4), [oct 2011] numeric (10,4),[q nov 2011] numeric (10,4), [nov 2011] numeric (10,4),[q dec 2011] numeric (10,4), [dec 2011] numeric (10,4),[q jan 2012] numeric (10,4), [jan 2012] numeric (10,4),[q feb 2012] numeric (10,4), [feb 2012] numeric (10,4),[sales feb 2012] numeric (10,4), [end of feb 2012 stock] numeric (10,4) )insert into @temptable select 'PF10100',95.8,7.0989,476.7,6.9892,985,6.9947,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1092.3,8.5255,1000,1455.1/* Solution by SwePeso*/-- Create a normalized staging tableCREATE TABLE #Temp ( Product NVARCHAR(35) NOT NULL, SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the staging table INSERT #Temp ( Product, SeqID, Quantity, Cost )SELECT Product, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT Product, CAST('20110101' AS DATETIME) AS thePeriod, [q jan 2011] AS Quantity, [jan 2011] AS Cost FROM @TempTable UNION ALL SELECT Product, '20110201', [q feb 2011], [feb 2011] FROM @TempTable UNION ALL SELECT Product, '20110301', [q mar 2011], [mar 2011] FROM @TempTable UNION ALL SELECT Product, '20110401', [q apr 2011], [apr 2011] FROM @TempTable UNION ALL SELECT Product, '20110501', [q may 2011], [may 2011] FROM @TempTable UNION ALL SELECT Product, '20110601', [q jun 2011], [jun 2011] FROM @TempTable UNION ALL SELECT Product, '20110701', [q jul 2011], [jul 2011] FROM @TempTable UNION ALL SELECT Product, '20110801', [q aug 2011], [aug 2011] FROM @TempTable UNION ALL SELECT Product, '20110901', [q sept 2011], [sept 2011] FROM @TempTable UNION ALL SELECT Product, '20111001', [q oct 2011], [oct 2011] FROM @TempTable UNION ALL SELECT Product, '20111101', [q nov 2011], [nov 2011] FROM @TempTable UNION ALL SELECT Product, '20111201', [q dec 2011], [dec 2011] FROM @TempTable UNION ALL SELECT Product, '20120101', [q jan 2012], [jan 2012] FROM @TempTable UNION ALL SELECT Product, '20120201', [q feb 2012], [feb 2012] FROM @TempTable UNION ALL SELECT Product, '99991101', [end of feb 2012 stock], 0 FROM @TempTable UNION ALL SELECT Product, '99991201', [sales feb 2012], 0 FROM @TempTable ) AS dWHERE Quantity IS NOT NULL-- Create a staging table for iterationCREATE TABLE #Iteration ( Product NVARCHAR(35), SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the iteration table with an initial value for each productINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT Product, SeqID, Quantity, CostFROM #TempWHERE SeqID = 1-- Iterate until all products has a zero or a negative quantity valueWHILE EXISTS(SELECT * FROM #Iteration WHERE Quantity > 0) AND @@ROWCOUNT > 0 UPDATE i SET i.SeqID = t.SeqID, i.Quantity = i.Quantity - t.Quantity, i.Cost = t.Cost FROM #Iteration AS i INNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = i.SeqID + 1 WHERE i.Quantity > 0-- Set all negative values to a positive valueUPDATE #IterationSET Quantity = ABS(Quantity)WHERE Quantity < 0-- Insert a new row for each product with previous last known costINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT t.Product, t.SeqID, t.Quantity - i.Quantity AS Quantity, w.CostFROM #Iteration AS iINNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = 0INNER JOIN #Temp AS w ON w.Product = i.Product AND w.SeqID = i.SeqID + 1-- Display the final resultSELECT Product, SUM(Quantity) AS Total, SUM(Quantity * Cost) / SUM(Quantity) AS AverageFROM #IterationGROUP BY Product--HAVING COUNT(*) = 2 -- Uncomment this line if you want all productsORDER BY Product-- Clean upDROP TABLE #Temp, #Iteration[/code] N 56°04'39.26"E 12°55'05.63" |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-03-16 : 15:11:44
|
you again started a new id with name Peso??------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-16 : 17:27:32
|
Didn't notice that. That response was from my cell phone. N 56°04'39.26"E 12°55'05.63" |
 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-03-16 : 17:52:54
|
quote: Originally posted by SwePeso Didn't notice that. That response was from my cell phone. N 56°04'39.26"E 12°55'05.63"
Oh ok..so that id still exists? ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-16 : 18:22:58
|
I thought not, but is does. N 56°04'39.26"E 12°55'05.63" |
 |
|
tempus
Starting Member
47 Posts |
Posted - 2012-03-20 : 03:58:48
|
Dear SwePesothe infinite loop has been solved with @@rownumber > 0 but now the result is incorect. if we take the following example :declare @TempTable TABLE( [Product] nvarchar (35),[q jan 2011] numeric (10,4), [jan 2011] numeric (10,4),[q feb 2011] numeric (10,4), [feb 2011] numeric (10,4) , [q mar 2011] numeric (10,4), [mar 2011] numeric (10,4),[q apr 2011] numeric (10,4), [apr 2011] numeric (10,4),[q may 2011] numeric (10,4), [may 2011] numeric (10,4), [q jun 2011] numeric (10,4), [jun 2011] numeric (10,4),[q jul 2011] numeric (10,4), [jul 2011] numeric (10,4),[q aug 2011] numeric (10,4), [aug 2011] numeric (10,4),[q sept 2011] numeric (10,4), [sept 2011] numeric (10,4),[q oct 2011] numeric (10,4), [oct 2011] numeric (10,4),[q nov 2011] numeric (10,4), [nov 2011] numeric (10,4),[q dec 2011] numeric (10,4), [dec 2011] numeric (10,4),[q jan 2012] numeric (10,4), [jan 2012] numeric (10,4),[q feb 2012] numeric (10,4), [feb 2012] numeric (10,4),[sales feb 2012] numeric (10,4), [end of feb 2012 stock] numeric (10,4) )insert into @TempTable select 'PF10250',829.8,10.0279,0,0,252.6,11.6828,0,0,432.4,9.6261,807.6,9.7684,0,0,0,0,646.9,9.235,413.2,9.2947,0,0,0,0,0,0,620.2,9.0702,638.2,520.2/* Solution by SwePeso*/-- Create a normalized staging tableCREATE TABLE #Temp ( Product NVARCHAR(35) NOT NULL, SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the staging table INSERT #Temp ( Product, SeqID, Quantity, Cost )SELECT Product, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT Product, CAST('20110101' AS DATETIME) AS thePeriod, [q jan 2011] AS Quantity, [jan 2011] AS Cost FROM @TempTable UNION ALL SELECT Product, '20110201', [q feb 2011], [feb 2011] FROM @TempTable UNION ALL SELECT Product, '20110301', [q mar 2011], [mar 2011] FROM @TempTable UNION ALL SELECT Product, '20110401', [q apr 2011], [apr 2011] FROM @TempTable UNION ALL SELECT Product, '20110501', [q may 2011], [may 2011] FROM @TempTable UNION ALL SELECT Product, '20110601', [q jun 2011], [jun 2011] FROM @TempTable UNION ALL SELECT Product, '20110701', [q jul 2011], [jul 2011] FROM @TempTable UNION ALL SELECT Product, '20110801', [q aug 2011], [aug 2011] FROM @TempTable UNION ALL SELECT Product, '20110901', [q sept 2011], [sept 2011] FROM @TempTable UNION ALL SELECT Product, '20111001', [q oct 2011], [oct 2011] FROM @TempTable UNION ALL SELECT Product, '20111101', [q nov 2011], [nov 2011] FROM @TempTable UNION ALL SELECT Product, '20111201', [q dec 2011], [dec 2011] FROM @TempTable UNION ALL SELECT Product, '20120101', [q jan 2012], [jan 2012] FROM @TempTable UNION ALL SELECT Product, '20120201', [q feb 2012], [feb 2012] FROM @TempTable UNION ALL SELECT Product, '99991101', [end of feb 2012 stock], 0 FROM @TempTable UNION ALL SELECT Product, '99991201', [sales feb 2012], 0 FROM @TempTable ) AS dWHERE Quantity IS NOT NULL-- Create a staging table for iterationCREATE TABLE #Iteration ( Product NVARCHAR(35), SeqID INT NOT NULL, Quantity MONEY NOT NULL, Cost MONEY NOT NULL, PRIMARY KEY ( Product, SeqID ) )-- Populate the iteration table with an initial value for each productINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT Product, SeqID, Quantity, CostFROM #TempWHERE SeqID = 1-- Iterate until all products has a zero or a negative quantity valueWHILE EXISTS(SELECT * FROM #Iteration WHERE Quantity > 0) AND @@ROWCOUNT > 0 UPDATE i SET i.SeqID = t.SeqID, i.Quantity = i.Quantity - t.Quantity, i.Cost = t.Cost FROM #Iteration AS i INNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = i.SeqID + 1 WHERE i.Quantity > 0-- Set all negative values to a positive valueUPDATE #IterationSET Quantity = ABS(Quantity)WHERE Quantity < 0-- Insert a new row for each product with previous last known costINSERT #Iteration ( Product, SeqID, Quantity, Cost )SELECT t.Product, t.SeqID, t.Quantity - i.Quantity AS Quantity, w.CostFROM #Iteration AS iINNER JOIN #Temp AS t ON t.Product = i.Product AND t.SeqID = 0INNER JOIN #Temp AS w ON w.Product = i.Product AND w.SeqID = i.SeqID + 1-- Display the final resultSELECT Product, SUM(Quantity) AS Total, SUM(Quantity * Cost) / SUM(Quantity) AS AverageFROM #IterationGROUP BY Product--HAVING COUNT(*) = 2 -- Uncomment this line if you want all productsORDER BY Product-- Clean upDROP TABLE #Temp, #Iterationthe ending stock is 520.2the sales is 638.2going back thru the table we see a production of 620.2 ending stock - last production is -100 as the cost of 9.0702so the sales start from here : 100 kg sold at 9.0702we need to go back until we cover all the ammount of sales ( 538.2 remaining ) the next production is 413.2 at cost of 9.2947still remaining 538.2-413.2 = 125 kg the next one is 646.9 at the cost of 9.235so the last 125 were sold at 9.235the average should be = [(100*9.0702)+(413.2*9.2947)+(125*9.235)]/638.2 = 9.24783but the average now shows = 1.4212 which is incorect. Im really sorry for the late reply.thanks in advance for the answer, Best regards, B. |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-20 : 09:35:58
|
Like this?declare @TempTable TABLE( [Product] nvarchar (35),[q jan 2011] numeric (10,4), [jan 2011] numeric (10,4),[q feb 2011] numeric (10,4), [feb 2011] numeric (10,4) , [q mar 2011] numeric (10,4), [mar 2011] numeric (10,4),[q apr 2011] numeric (10,4), [apr 2011] numeric (10,4),[q may 2011] numeric (10,4), [may 2011] numeric (10,4), [q jun 2011] numeric (10,4), [jun 2011] numeric (10,4),[q jul 2011] numeric (10,4), [jul 2011] numeric (10,4),[q aug 2011] numeric (10,4), [aug 2011] numeric (10,4),[q sept 2011] numeric (10,4), [sept 2011] numeric (10,4),[q oct 2011] numeric (10,4), [oct 2011] numeric (10,4),[q nov 2011] numeric (10,4), [nov 2011] numeric (10,4),[q dec 2011] numeric (10,4), [dec 2011] numeric (10,4),[q jan 2012] numeric (10,4), [jan 2012] numeric (10,4),[q feb 2012] numeric (10,4), [feb 2012] numeric (10,4),[sales feb 2012] numeric (10,4), [end of feb 2012 stock] numeric (10,4) )insert into @TempTable select 'PF10100',95.8,7.0989,476.7,6.9892,985,6.9947,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1092.3,8.5255,1000,1455.1 union allselect 'PF10250',829.8,10.0279,0,0,252.6,11.6828,0,0,432.4,9.6261,807.6,9.7684,0,0,0,0,646.9,9.235,413.2,9.2947,0,0,0,0,0,0,620.2,9.0702,638.2,520.2/* Solution by SwePeso*/-- Create a normalized staging tableCREATE TABLE #Temp ( Product NVARCHAR(35) NOT NULL, SeqID INT NOT NULL, Remaining MONEY, Quantity MONEY, Items MONEY, Cost MONEY, Countdown MONEY, PRIMARY KEY ( Product, SeqID ) )-- Populate the staging table INSERT #Temp ( Product, SeqID, Quantity, Cost )SELECT Product, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT Product, CAST('20110101' AS DATETIME) AS thePeriod, [q jan 2011] AS Quantity, [jan 2011] AS Cost FROM @TempTable UNION ALL SELECT Product, '20110201', [q feb 2011], [feb 2011] FROM @TempTable UNION ALL SELECT Product, '20110301', [q mar 2011], [mar 2011] FROM @TempTable UNION ALL SELECT Product, '20110401', [q apr 2011], [apr 2011] FROM @TempTable UNION ALL SELECT Product, '20110501', [q may 2011], [may 2011] FROM @TempTable UNION ALL SELECT Product, '20110601', [q jun 2011], [jun 2011] FROM @TempTable UNION ALL SELECT Product, '20110701', [q jul 2011], [jul 2011] FROM @TempTable UNION ALL SELECT Product, '20110801', [q aug 2011], [aug 2011] FROM @TempTable UNION ALL SELECT Product, '20110901', [q sept 2011], [sept 2011] FROM @TempTable UNION ALL SELECT Product, '20111001', [q oct 2011], [oct 2011] FROM @TempTable UNION ALL SELECT Product, '20111101', [q nov 2011], [nov 2011] FROM @TempTable UNION ALL SELECT Product, '20111201', [q dec 2011], [dec 2011] FROM @TempTable UNION ALL SELECT Product, '20120101', [q jan 2012], [jan 2012] FROM @TempTable UNION ALL SELECT Product, '20120201', [q feb 2012], [feb 2012] FROM @TempTable UNION ALL SELECT Product, '99991101', [end of feb 2012 stock], NULL FROM @TempTable UNION ALL SELECT Product, '99991201', [sales feb 2012], NULL FROM @TempTable ) AS dWHERE Quantity <> 0DECLARE @SeqID INT = 2-- Initialize staging table with starting valuesUPDATE tSET t.Remaining = q.Quantity + w.Quantity - t.Quantity, t.Items = w.Quantity - t.Quantity, t.Countdown = q.Quantity - ABS(w.Quantity - t.Quantity)FROM #Temp AS tINNER JOIN #Temp AS w ON w.Product = t.Product AND w.SeqID = 1INNER JOIN #Temp AS q ON q.Product = t.Product AND q.SeqID = 0WHERE t.SeqID = 2-- Iterate until no more items to processWHILE @@ROWCOUNT > 0 BEGIN SET @SeqID = @SeqID + 1 UPDATE t SET t.Remaining = CASE WHEN w.Items < 0 THEN w.Remaining ELSE w.Items END, t.Items = CASE WHEN w.Items < 0 THEN t.Quantity ELSE w.Items - t.Quantity END, t.Countdown = w.Countdown - ABS( CASE WHEN w.Items < 0 THEN t.Quantity ELSE w.Items - t.Quantity END ) FROM #Temp AS t INNER JOIN #Temp AS w ON w.Product = t.Product AND w.SeqID = t.SeqID - 1 WHERE t.SeqID = @SeqID AND w.Countdown > 0 END-- Delete unwanted rowsDELETEFROM #TempWHERE Remaining IS NULL AND SeqID > 0-- Correct last row per productUPDATE tSET t.Items = CASE WHEN t.Quantity = t.Items THEN w.Quantity + q.Items ELSE q.Countdown ENDFROM #Temp AS tINNER JOIN #Temp AS w ON w.Product = t.Product AND w.SeqID = 0INNER JOIN #Temp AS q ON q.Product = t.Product AND q.SeqID = t.SeqID - 1WHERE t.Countdown < 0-- Display the final resultSELECT t.Product, SUM(ABS(t.Items) * t.Cost) / SUM(ABS(t.Items)) AS AverageFROM #Temp AS tINNER JOIN ( SELECT Product, MIN(SeqID) AS SeqID FROM #Temp WHERE Items < 0 GROUP BY Product ) AS w ON w.Product = t.Product AND w.SeqID <= t.SeqIDGROUP BY t.ProductORDER BY t.Product-- Clean upDROP TABLE #Temp N 56°04'39.26"E 12°55'05.63" |
 |
|
tempus
Starting Member
47 Posts |
Posted - 2012-03-23 : 05:29:17
|
Dear SwePeso, for some reason i only get results for 167 products ( and the result is correct) , but my table contains 366 product ( i only got in the table now products that have quantity sold greater than 0 ) .i tried to figure out why they dont appear in the select but with no luck. If you got any kind of sugestion how to verify please tell me. Best regards, B. |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2012-03-23 : 05:38:42
|
I can't. If I continue with this, I need access to ALL your data, otherwise everything from my part is a fair guess. N 56°04'39.26"E 12°55'05.63" |
 |
|
stepson
Aged Yak Warrior
545 Posts |
Posted - 2012-03-23 : 07:07:50
|
you filter the result when you insert into #temp : WHERE Quantity <> 0add at end something like ,before Clean up :INSERT #Temp ( Product, SeqID, Quantity, Cost )SELECT Product, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT Product, CAST('20110101' AS DATETIME) AS thePeriod, [q jan 2011] AS Quantity, [jan 2011] AS Cost FROM @TempTable UNION ALL SELECT Product, '20110201', [q feb 2011], [feb 2011] FROM @TempTable UNION ALL SELECT Product, '20110301', [q mar 2011], [mar 2011] FROM @TempTable UNION ALL SELECT Product, '20110401', [q apr 2011], [apr 2011] FROM @TempTable UNION ALL SELECT Product, '20110501', [q may 2011], [may 2011] FROM @TempTable UNION ALL SELECT Product, '20110601', [q jun 2011], [jun 2011] FROM @TempTable UNION ALL SELECT Product, '20110701', [q jul 2011], [jul 2011] FROM @TempTable UNION ALL SELECT Product, '20110801', [q aug 2011], [aug 2011] FROM @TempTable UNION ALL SELECT Product, '20110901', [q sept 2011], [sept 2011] FROM @TempTable UNION ALL SELECT Product, '20111001', [q oct 2011], [oct 2011] FROM @TempTable UNION ALL SELECT Product, '20111101', [q nov 2011], [nov 2011] FROM @TempTable UNION ALL SELECT Product, '20111201', [q dec 2011], [dec 2011] FROM @TempTable UNION ALL SELECT Product, '20120101', [q jan 2012], [jan 2012] FROM @TempTable UNION ALL SELECT Product, '20120201', [q feb 2012], [feb 2012] FROM @TempTable UNION ALL SELECT Product, '99991101', [end of feb 2012 stock], NULL FROM @TempTable UNION ALL SELECT Product, '99991201', [sales feb 2012], NULL FROM @TempTable ) AS dWHERE Quantity = 0 |
 |
|
tempus
Starting Member
47 Posts |
Posted - 2012-04-03 : 02:44:42
|
i give up.here's the whole thing: table creation: USE [iScalaDB]GO/****** Object: Table [dbo].[BT_rmc_uri_reale] Script Date: 04/03/2012 09:33:58 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[BT_rmc_uri_reale]( [cod produs] [nvarchar](35) NOT NULL, [denumire produs] [nvarchar](25) NOT NULL, [grupa produs] [nvarchar](10) NOT NULL, [q ianuarie 2011] [numeric](10, 2) NULL, [ianuarie 2011] [numeric](10, 4) NULL, [q februarie 2011] [numeric](10, 2) NULL, [februarie 2011] [numeric](10, 4) NULL, [q martie 2011] [numeric](10, 2) NULL, [martie 2011] [numeric](10, 4) NULL, [q aprilie 2011] [numeric](10, 2) NULL, [aprilie 2011] [numeric](10, 4) NULL, [q mai 2011] [numeric](10, 2) NULL, [mai 2011] [numeric](10, 4) NULL, [q iunie 2011] [numeric](10, 2) NULL, [iunie 2011] [numeric](10, 4) NULL, [q iulie 2011] [numeric](10, 2) NULL, [iulie 2011] [numeric](10, 4) NULL, [q august 2011] [numeric](10, 2) NULL, [august 2011] [numeric](10, 4) NULL, [q septembrie 2011] [numeric](10, 2) NULL, [septembrie 2011] [numeric](10, 4) NULL, [q octombrie 2011] [numeric](10, 2) NULL, [octombrie 2011] [numeric](10, 4) NULL, [q noiembrie 2011] [numeric](10, 2) NULL, [noiembrie 2011] [numeric](10, 4) NULL, [q decembrie 2011] [numeric](10, 2) NULL, [decembrie 2011] [numeric](10, 4) NULL, [q ianuarie 2012] [numeric](10, 2) NULL, [ianuarie 2012] [numeric](10, 4) NULL, [q februarie 2012] [numeric](10, 2) NULL, [februarie 2012] [numeric](10, 4) NULL, [q martie 2012] [numeric](10, 2) NULL, [martie 2012] [numeric](10, 4) NULL, [q aprilie 2012] [numeric](10, 2) NULL, [aprilie 2012] [numeric](10, 4) NULL, [q mai 2012] [numeric](10, 2) NULL, [mai 2012] [numeric](10, 4) NULL, [q iunie 2012] [numeric](10, 2) NULL, [iunie 2012] [numeric](10, 4) NULL, [q iulie 2012] [numeric](10, 2) NULL, [iulie 2012] [numeric](10, 4) NULL, [q august 2012] [numeric](10, 2) NULL, [august 2012] [numeric](10, 4) NULL, [q septembrie 2012] [numeric](10, 2) NULL, [septembrie 2012] [numeric](10, 4) NULL, [q octombrie 2012] [numeric](10, 2) NULL, [octombrie 2012] [numeric](10, 4) NULL, [q noiembrie 2012] [numeric](10, 2) NULL, [noiembrie 2012] [numeric](10, 4) NULL, [q decembrie 2012] [numeric](10, 2) NULL, [decembrie 2012] [numeric](10, 4) NULL, [q ianuarie 2013] [numeric](10, 2) NULL, [ianuarie 2013] [numeric](10, 4) NULL, [sales feb 2012] [numeric](10, 4) NULL, [end of feb 2012 stock] [numeric](10, 4) NULL) ON [PRIMARY]GOive inserted the data to an excel which can be found here. It needs to be inserted into the table. i dont know if im allowed to post a link to an external website but here i go ( if im not allowed please delete) :http://www.2shared.com/document/0O4CLpn5/data_to_be_inserted_into_table.htmlthe last script that i use :/* Solution by SwePeso*/-- Create a normalized staging tableCREATE TABLE #Temp ( [cod produs] NVARCHAR(35) NOT NULL, SeqID INT NOT NULL, Remaining MONEY, Quantity MONEY, Items MONEY, Cost MONEY, Countdown MONEY, PRIMARY KEY ( [cod produs], SeqID ) )-- Populate the staging table INSERT #Temp ( [cod produs], SeqID, Quantity, Cost )SELECT [cod produs], ROW_NUMBER() OVER (PARTITION BY [cod produs] ORDER BY thePeriod DESC) - 1 AS SeqID, Quantity, CostFROM ( SELECT [cod produs], CAST('20110101' AS DATETIME) AS thePeriod, [q ianuarie 2011] AS Quantity, [ianuarie 2011] AS Cost FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110201', [q februarie 2011], [februarie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110301', [q martie 2011], [martie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110401', [q aprilie 2011], [aprilie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110501', [q mai 2011], [mai 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110601', [q iunie 2011], [iunie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110701', [q iulie 2011], [iulie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110801', [q august 2011], [august 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20110901', [q septembrie 2011], [septembrie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20111001', [q octombrie 2011], [octombrie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20111101', [q noiembrie 2011], [noiembrie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20111201', [q decembrie 2011], [decembrie 2011] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20120101', [q ianuarie 2012], [ianuarie 2012] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '20120201', [q februarie 2012], [februarie 2012] FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '99991101', [end of feb 2012 stock], 0 FROM BT_rmc_uri_reale UNION ALL SELECT [cod produs], '99991201', [sales feb 2012], 0 FROM BT_rmc_uri_reale ) AS dWHERE Quantity <>0--select * from BT_rmc_uri_reale order by [cod produs]DECLARE @SeqID INT set @SeqID = 2-- Initialize staging table with starting valuesUPDATE tSET t.Remaining = q.Quantity + w.Quantity - t.Quantity, t.Items = w.Quantity - t.Quantity, t.Countdown = q.Quantity - ABS(w.Quantity - t.Quantity)FROM #Temp AS tINNER JOIN #Temp AS w ON w.[cod produs] = t.[cod produs] AND w.SeqID = 1INNER JOIN #Temp AS q ON q.[cod produs] = t.[cod produs] AND q.SeqID = 0WHERE t.SeqID = 2-- select * from #Temp-- Iterate until no more items to processWHILE @@ROWCOUNT > 0 BEGIN SET @SeqID = @SeqID + 1 UPDATE t SET t.Remaining = CASE WHEN w.Items < 0 THEN w.Remaining ELSE w.Items END, t.Items = CASE WHEN w.Items < 0 THEN t.Quantity ELSE w.Items - t.Quantity END, t.Countdown = w.Countdown - ABS( CASE WHEN w.Items < 0 THEN t.Quantity ELSE w.Items - t.Quantity END ) FROM #Temp AS t INNER JOIN #Temp AS w ON w.[cod produs] = t.[cod produs] AND w.SeqID = t.SeqID - 1 WHERE t.SeqID = @SeqID AND w.Countdown > 0 END-- Delete unwanted rowsDELETEFROM #TempWHERE Remaining IS NULL AND SeqID > 0-- Correct last row per [cod produs]UPDATE tSET t.Items = CASE WHEN t.Quantity = t.Items THEN w.Quantity + q.Items ELSE q.Countdown ENDFROM #Temp AS tINNER JOIN #Temp AS w ON w.[cod produs] = t.[cod produs] AND w.SeqID = 0INNER JOIN #Temp AS q ON q.[cod produs] = t.[cod produs] AND q.SeqID = t.SeqID - 1WHERE t.Countdown < 0-- Display the final resultSELECT t.[cod produs], SUM(ABS(t.Items) * t.Cost) / SUM(ABS(t.Items)) AS AverageFROM #Temp AS tINNER JOIN ( SELECT [cod produs], MIN(SeqID) AS SeqID FROM #Temp WHERE Items < 0 GROUP BY [cod produs] ) AS w ON w.[cod produs] = t.[cod produs] AND w.SeqID <= t.SeqIDGROUP BY t.[cod produs]ORDER BY t.[cod produs]-- Clean upDROP TABLE #TempThe results i get is for 167 products. the cost seem to be corect also. I need the result for all the products in the table thou'.Sincerly many thanks to all the time spent for helping me. Best wishes,B. |
 |
|
|
|
|