Lessons › SQL › Deep Dive: Advanced Window Functions
SQL lesson
Moving averages with AVG() OVER
A moving average (calculated by averaging a sliding window of rows around each point) smooths out short-term noise so the underlying trend becomes visible.
Try this lesson free →Example
Smoothing Retail Sales Trends with Moving Averages
SELECT sale_date, revenue, AVG(revenue) OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3day_revenue FROM store_sales WHERE channel = 'Online' ORDER BY sale_date| sale_date | revenue | moving_avg_3day_revenue |
|---|---|---|
| 2024-03-01 | 12400.0 | 12400.0 |
| 2024-03-02 | 9800.0 | 11100.0 |
| 2024-03-03 | 15200.0 | 12466.67 |
| 2024-03-04 | 11600.0 | 12200.0 |
| 2024-03-05 | 13900.0 | 13566.67 |
Step by step
- Run the query without AVG so you can see what the unfiltered values look like.
SELECT sale_date, revenue, revenue OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3day_revenue FROM store_sales WHERE channel = 'Online' ORDER BY sale_date; - AVG returns the mean of the values in a column.
SELECT sale_date, revenue, AVG(revenue) OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3day_revenue FROM store_sales WHERE channel = 'Online' ORDER BY sale_date; - AS gives the AVG result a friendly column name so the output reads cleanly.
SELECT sale_date, revenue, AVG(revenue) AS avg_result OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3day_revenue FROM store_sales WHERE channel = 'Online' ORDER BY sale_date;
Practice
1. Using orders, write a query for a 7-row moving average of revenue ordered by order_date.
SELECT order_date, AVG(revenue) OVER (ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) FROM orders2. Using store_sales, write a query for a 3-row moving average of revenue ordered by sale_date.
SELECT sale_date, AVG(revenue) OVER (ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) FROM store_sales3. Using products, write a query for a 7-row moving average of price ordered by category.
SELECT category, AVG(price) OVER (ORDER BY category ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) FROM products4. Using employees, write a query for a 3-row moving average of salary ordered by hire_date.
SELECT hire_date, AVG(salary) OVER (ORDER BY hire_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) FROM employees5. Using reviews, write a query for a 3-row moving average of rating ordered by review_date.
SELECT review_date, AVG(rating) OVER (ORDER BY review_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) FROM reviewsLearn it by doing. This lesson is a short hands-on level on Bampaa: see it work, then build and write it yourself, with instant feedback.
Try this lesson free →