Tuesday, August 5, 2014

Moving average of an average: TSQL

We track water temperature data over a wide variety of locations and want to be able to report a 7 day moving average of the average temperature for a given day.  We're using Microsoft SQL Server 2012 which has nifty OVER and PARTITION functions that help.


First I noticed that I need to calculate the average temperature and then calculate the moving average of that value.  It seemed to me what I really wanted was to be able to do the simple average aggregate using a GROUP BY date, and then pipe that resultset to an OVER PARTITION query. 


Here's how I ended up writing it:


WITH DAILY_TEMP_AVG AS
(
 SELECT
  convert(date, ReadingDateTime) as TempDate,
  avg(WaterTemperature) as AvgWaterTemp,
  LocationId
 FROM WaterTemp_VW
 GROUP BY LocationId, convert(date, ReadingDateTime)
)
SELECT
 LocationId,
 TempDate,
 AvgWaterTemp,
 avg(AvgWaterTemp) over (PARTITION by locationid
       ORDER BY TempDate
       ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING) as theaverage
 FROM DAILY_TEMP_AVG
 WHERE LocationId = 1150
 AND TempDate BETWEEN '6/1/2013' AND '7/1/2013'