I have a table that looks something like this:
city | date | value |
---|---|---|
DC | 2020-01-01 | 10 |
DC | 2020-01-01 | 23 |
DC | 2020-01-02 | 43 |
NYC | 2020-01-01 | 43 |
NYC | 2020-01-02 | 23 |
NYC | 2020-01-03 | 10 |
There are multiple values per city, per date. I'm having a hard time calculating the forward looking 30 day average because the condition in the rolling average should be based on the date and not based on the number of rows. I want the output to be something like this:
city | date | value |
---|---|---|
DC | 2020-01-01 | 25.33 |
DC | 2020-01-02 | 43 |
NYC | 2020-01-01 | 25.33 |
NYC | 2020-01-02 | 16.5 |
NYC | 2020-01-03 | 10 |
So I can't do something like this:
AVG(value) OVER (
PARTITION BY city, date
ORDER BY date DESC
ROWS BETWEEN 31 PRECEDING AND 1 PRECEDING
)
joining the table on itself like this:
SELECT t1.city, t1.date, avg(t2.values)
FROM table1 t1
JOIN table1 t2 ON t1.city=t2.city
AND t2.date < DATEADD('day',31,t1.date)
AND t2.date >= t1.date
isn't an option because it's quite large and takes forever. How do I do this?
You want to use RANGE instead of ROWS in your window frame. But that requires ordering by a number. So you need to do:
over (... order by datediff(date,'1970-01-01') asc range between 31 preceding and 1 following)
(Though I think you want 0 following?)