I am trying to compute efficiently (using SQL Server 2008) the moving average of the ProductCount over a period of 24 hours. For every single row in the Product table, I\'d
Well, the fact that you need to calculate the average for every hour, actually makes this simpler, since you just need to SUM
the product count and divide it by a fixed number (24). So I think that this will get the results you want (though in this particular case, a cursor by be actually faster):
SELECT A.*, B.ProductCount/24 DailyMovingAverage
FROM ProductInventory A
OUTER APPLY ( SELECT SUM(ProductCount) ProductCount
FROM ProductInventory
WHERE ProductName = A.ProductName
AND [Date] BETWEEN DATEADD(HOUR,-23,A.[Date]) AND A.[Date]) B
I added to Lamak's answer to include min/max:
SELECT *
FROM ProductInventory A
OUTER APPLY (
SELECT
SUM(ProductCount) / 24 AS DailyMovingAverage,
MAX(ProductCount) AS MaxProductCount,
CASE COUNT(*) WHEN 24 THEN MIN(ProductCount) ELSE 0 END AS MinProductCount
FROM ProductInventory
WHERE ProductName = A.ProductName
AND [Date] BETWEEN DATEADD(HOUR, -23, A.[Date]) AND A.[Date]) B
To account for missing records, check that there were indeed 24 records in the last 24 hours before using MIN(ProductCount)
, and return 0 otherwise.
Working SQL Fiddle, with a bunch (bushel?) of Oranges added to show the MinProductCount working