For example, I have the following sale table:
| week | sales |
|---|---|
| 1 | 10 |
| 1 | 15 |
| 2 | 5 |
| 2 | 10 |
| 3 | 10 |
| 3 | 20 |
| 4 | 5 |
| 4 | 10 |
| 5 | 15 |
| 5 | 10 |
I want to have a SQL query like this:
SELECT '1-3' AS period, SUM(sales)
FROM sale
WHERE 1<=week AND week<=3
GROUP BY period
UNION ALL
SELECT '2-4' AS period, SUM(sales)
FROM sale
WHERE 2<=week AND week<=4
GROUP BY period
UNION ALL
SELECT '3-5' AS period, SUM(sales)
FROM sale
WHERE 3<=week AND week<=5
GROUP BY period
When the number of rolling windows is large, the above SQL query will be cumbersome. Is there a workaround?
I tried to think of using carterian product. However, it will generate some unneeded rows.
A simple and efficient solution is to use window functions with rolling window frame clause. However, if there are missing weeks in the data (e.g. week 1, 3, 4) then frame will be calculated incorrectly or some expected data will be missing.
A complete solution is to add the missing weeks using some row generator technique (e.g. recursive cte) then use window functions to calculate sum over rolling window:
This approach should work in all RDBMS that support recursive CTEs and window functions. Some RDBMs have built-in row generator functions.
DB<>Fiddle