How do you create a moving average in SQL?
Current table:
Date Clicks
2012-05-01 2,230
2012-05-02 3,150
2012-05-03 5,520
2012-05-04 1,330
2012-05-05 2,260
2012-05-06 3,540
2012-05-07 2,330
Desired table or output:
Date Clicks 3 day Moving Average
2012-05-01 2,230
2012-05-02 3,150
2012-05-03 5,520 4,360
2012-05-04 1,330 3,330
2012-05-05 2,260 3,120
2012-05-06 3,540 3,320
2012-05-07 2,330 3,010
Example here.
Obviously you can change the interval to whatever you need. You could also use count() instead of a magic number to make it easier to change, but that will also slow it down.
General template for rolling averages that scales well for large data sets
And for weighted rolling averages:
I'm not sure that your expected result (output) shows classic "simple moving (rolling) average" for 3 days. Because, for example, the first triple of numbers by definition gives:
but you expect
4.360
and it's confusing.Nevertheless, I suggest the following solution, which uses window-function
AVG
. This approach is much more efficient (clear and less resource-intensive) thanSELF-JOIN
introduced in other answers (and I'm surprised that no one has given a better solution).You see that
AVG
is wrapped withcase when rownum >= p.days then
to forceNULL
s in first rows, where "3 day Moving Average" is meaningless.We can apply Joe Celko's "dirty" left outer join method (as cited above by Diego Scaravaggi) to answer the question as it was asked.
This query:
Generates the requested output: