SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed
SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog
Back to Blog
2025-12-29
3 min read

Calculating Moving Averages and Rolling Windows in SQL

sqltutorialtime-serieswindow-functionsmoving-average

Data is noisy. Daily sales spike on weekends, drop on holidays, and fluctuate randomly. To see the real trend, analysts use Moving Averages (or Rolling Averages).

A jagged time series smoothed by a rolling moving average line
A jagged time series smoothed by a rolling moving average line

A moving average takes the current value and averages it with a set number of previous values.

The Window Function Formula

Window frame diagram highlighting ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
Window frame diagram highlighting ROWS BETWEEN 2 PRECEDING AND CURRENT ROW

To calculate a moving average in SQL, you use the standard AVG() aggregate function but apply it over a "window" of rows.

AVG(column) OVER (
  ORDER BY date_column
  ROWS BETWEEN X PRECEDING AND CURRENT ROW
)
  • ORDER BY date_column: Ensures rows are processed in chronological order.
  • ROWS BETWEEN: Defines the "frame size".
    • For a 7-Day Moving Average, you want today + the previous 6 days. So: ROWS BETWEEN 6 PRECEDING AND CURRENT ROW.
    • For a 3-Day Moving Average: ROWS BETWEEN 2 PRECEDING AND CURRENT ROW.

Real-World Example: Daily Stock Prices

Let's look at a volatile stock price and smooth it out.

1. Daily Volatility

First, observe the raw daily prices.

Interactive SQL
Loading...

2. Calculating the 3-Day Moving Average

Now, let's calculate the 3-day moving average. For Jan 3rd, it will average prices from Jan 1, 2, and 3.

Interactive SQL
Loading...

Result Analysis:

  • On Jan 4, the price dropped to $90.
  • The Moving Average was (102+104+90)/3 = 98.66.
  • Notice how the moving average ($98.66) is less extreme than the drop ($90), showing the smoothing effect.

Handling the "Start" of the Window

You might notice that the first row is just the average of itself, and the second row is the average of 2 days. The window grows until it hits the full size (3 days).

If you want to strictly enforce that you ONLY calculate when you have full 3 days of data, you'd need slightly more complex logic (often involving COUNT() OVER (...) to check the window size), but for most visual trend/charting purposes, the growing window at the start is acceptable.

Centered vs Trailing Windows

The examples above differ from "Centered" moving averages, which look ahead and behind.

  • Trailing (Standard): ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  • Centered: ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING

Centered averages are good for historical analysis but impossible for real-time forecasting (since you don't know tomorrow's price yet!).

Practice Challenge

Try modifying the query to calculate a Cumulative Average (running average of all time) by removing the ROWS clause entirely or using ROWS UNBOUNDED PRECEDING.

Conclusion

Window functions with frame specifications (ROWS BETWEEN) give you precise control over rolling calculations. Whether it's stock prices, website traffic, or server load, Moving Averages help you ignore the noise and focus on the signal.

Share this article:

Related Articles

sqltutorial

Year-over-Year Growth Analysis in SQL

Calculate growth rates like a pro. Learn how to use the LAG() window function to compare current values with past data.

Read more
sqlwindow-functions

SQL Window Frames: ROWS vs RANGE

Learn how ROWS and RANGE window frames change results, avoid hidden pitfalls, and build correct moving calculations with clear, runnable examples.

Read more
sqltime-series

Time Series Analysis with SQL: Trends, Growth, and Moving Averages

Turn raw timestamps into business insights. Learn how to calculate Month-over-Month growth and smooth out noisy data with 7-day moving averages.

Read more
Previous

Data Cleaning with SQL: From Messy to Masterpiece

Next

Customer Segmentation with RFM Analysis in SQL

Comments

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed