-- Creating tableCREATE TABLE year_week_value ( year INT, week INT, value INT ); -- Inserting test valuesINSERT year_week_valueVALUES (2011,49,3000),(2011,50,5000),(2011,51,6000),(2011,52,7000),(2012,1,3000),(2012,2,5000),(2012,3,6000),(2012,4,7000),(2012,5,8000),(2012,6,9000),(2012,7,1000),(2012,8,6000);-- Resultant querySELECT a.year, a.week, .25 * ( Isnull(b.value, 0) + Isnull(c.value, 0) + Isnull(d.value, 0) + Isnull(e.value, 0) ) AvgValFROM year_week_value a LEFT JOIN year_week_value b ON b.year = Year(Dateadd(wk, a.week - 2, Dateadd(year, a.year - 1900, 0))) AND b.week = Datepart(wk, Dateadd(wk, a.week - 2, 0)) LEFT JOIN year_week_value c ON c.year = Year(Dateadd(wk, a.week - 3, Dateadd(year, a.year - 1900, 0))) AND c.week = Datepart(wk, Dateadd(wk, a.week - 3, 0)) LEFT JOIN year_week_value d ON d.year = Year(Dateadd(wk, a.week - 4, Dateadd(year, a.year - 1900, 0))) AND d.week = Datepart(wk, Dateadd(wk, a.week - 4, 0)) LEFT JOIN year_week_value e ON e.year = Year(Dateadd(wk, a.week - 5, Dateadd(year, a.year - 1900, 0))) AND e.week = Datepart(wk, Dateadd(wk, a.week - 5, 0))ORDER BY a.year, a.week
Create Table Ex1 ( YEAR int, WEEKS int, VALUE int ) Insert Into Ex1 Select 2012, 1, 3000Union ALL Select 2012, 2, 5000Union ALL Select 2012, 3, 6000Union ALL Select 2012, 4, 7000Union ALL Select 2012, 5, 8000Union ALL Select 2012, 6, 9000Union ALL Select 2012, 7, 1000Union ALL Select 2012, 8, 6000 ;With CTE As ( Select *, ROW_NUMBER() Over(Order By Year, Weeks) As rn From Ex1 )Select *, (Case When (Select Count(*) From CTE Where rn < a.rn) >= 4 Then (Select AVG(VALUE) From CTE As b Where b.rn IN(Select Top 4 rn From CTE Where rn < a.rn Order By rn DESC)) Else '' End) As AvgValueFrom CTE As aOrder By YEAR, WEEKS
SELECT year, week, value, ISNULL(AvgVal,0) AS AvgValFROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) a(year,week,value,pos)OUTER APPLY (SELECT SUM(b.value)/(COUNT(1)*1.00) FROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) b(year,week,value,pos) WHERE a.pos >= b.pos AND a.pos-4 <= b.pos) ab(AvgVal);
SELECT year, week, value, ISNULL(AvgVal,0) AS AvgValFROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) a(year,week,value,pos)OUTER APPLY (SELECT SUM(b.value)/(COUNT(1)*1.00) FROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) b(year,week,value,pos) WHERE a.pos > b.pos AND a.pos-5 < b.pos) ab(AvgVal);
-- Creating tableCREATE TABLE year_week_value (year INT, week INT, value INT);-- Inserting test valuesINSERT year_week_valueVALUES (2011, 49, 3000), (2011, 50, 5000), (2011, 51, 6000), (2011, 52, 7000), (2012, 1, 3000), (2012, 2, 5000), (2012, 3, 6000), (2012, 4, 7000), (2012, 5, 8000), (2012, 6, 9000), (2012, 7, 1000), (2012, 8, 6000);
-- Lokesh VijSELECT a.year, a.week, .25 * (Isnull(b.value, 0) + Isnull(c.value, 0) + Isnull(d.value, 0) + Isnull(e.value, 0)) AvgVal, A.valueFROM year_week_value aLEFT JOIN year_week_value b ON b.year = Year(Dateadd(wk, a.week - 2, Dateadd(year, a.year - 1900, 0))) AND b.week = Datepart(wk, Dateadd(wk, a.week - 2, 0))LEFT JOIN year_week_value c ON c.year = Year(Dateadd(wk, a.week - 3, Dateadd(year, a.year - 1900, 0))) AND c.week = Datepart(wk, Dateadd(wk, a.week - 3, 0))LEFT JOIN year_week_value d ON d.year = Year(Dateadd(wk, a.week - 4, Dateadd(year, a.year - 1900, 0))) AND d.week = Datepart(wk, Dateadd(wk, a.week - 4, 0))LEFT JOIN year_week_value e ON e.year = Year(Dateadd(wk, a.week - 5, Dateadd(year, a.year - 1900, 0))) AND e.week = Datepart(wk, Dateadd(wk, a.week - 5, 0))ORDER BY a.year, a.week;-- vinu512WITH CTEAS (SELECT *, ROW_NUMBER() OVER (ORDER BY year, week) AS rn FROM year_week_value )SELECT *, (CASE WHEN (SELECT Count(*) FROM CTE WHERE rn < a.rn) >= 4 THEN (SELECT AVG(VALUE) FROM CTE AS b WHERE b.rn IN (SELECT TOP 4 rn FROM CTE WHERE rn < a.rn ORDER BY rn DESC )) ELSE '' END) AS AvgValueFROM CTE AS aORDER BY year, week; -- CadavreSELECT year, week, value, ISNULL(AvgVal,0) AS AvgValFROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) a(year,week,value,pos)OUTER APPLY (SELECT SUM(b.value)/(COUNT(1)*1.00) FROM (SELECT year, week, value, ROW_NUMBER() OVER(ORDER BY year,week) FROM year_week_value) b(year,week,value,pos) WHERE a.pos >= b.pos AND a.pos-4 <= b.pos) ab(AvgVal);
---------------------------------------------------------------------------Lokesh Vij---------------------------------------------------------------------------year week AvgVal value----------- ----------- --------------------------------------- -----------2011 49 0.00 30002011 50 750.00 50002011 51 2000.00 60002011 52 3500.00 70002012 1 5250.00 30002012 2 5250.00 50002012 3 5250.00 60002012 4 5250.00 70002012 5 5250.00 80002012 6 6500.00 90002012 7 7500.00 10002012 8 6250.00 6000------------------------------------------------------------------------------------------------------------------------------------------------------vinu512---------------------------------------------------------------------------year week value rn AvgValue----------- ----------- ----------- -------------------- -----------2011 49 3000 1 02011 50 5000 2 02011 51 6000 3 02011 52 7000 4 02012 1 3000 5 52502012 2 5000 6 52502012 3 6000 7 52502012 4 7000 8 52502012 5 8000 9 52502012 6 9000 10 65002012 7 1000 11 75002012 8 6000 12 6250------------------------------------------------------------------------------------------------------------------------------------------------------Cadavre---------------------------------------------------------------------------year week value AvgVal----------- ----------- ----------- ---------------------------------------2011 49 3000 0.0000000000000002011 50 5000 3000.0000000000000002011 51 6000 4000.0000000000000002011 52 7000 4666.6666666666666662012 1 3000 5250.0000000000000002012 2 5000 5250.0000000000000002012 3 6000 5250.0000000000000002012 4 7000 5250.0000000000000002012 5 8000 5250.0000000000000002012 6 9000 6500.0000000000000002012 7 1000 7500.0000000000000002012 8 6000 6250.000000000000000