pbPassingBI
/
Window functions advanced 5 min

Running totals and moving averages

Cumulative sums, moving windows, and getting the frame right.

What you'll be able to do
  • Write a running total
  • Write a moving average
  • Reset a cumulative sum per group

Running total

SELECT order_date, total,
       SUM(total) OVER (ORDER BY order_date
                        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
FROM orders;

The frame can be omitted — ORDER BY alone gives the same default — but writing it makes the intent explicit and avoids the ROWS/RANGE ambiguity when dates repeat.

Resetting per group

SUM(total) OVER (PARTITION BY region ORDER BY order_date
                 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)

The cumulative sum restarts at each region.

Moving average

AVG(revenue) OVER (ORDER BY mth
                   ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS ma_3

A three-period trailing average. The first two rows average fewer values rather than returning null, which is worth knowing before you chart it.

Use ROWS, not RANGE, or ties on the ordering column pull in extra rows.

Percent of running total

SUM(total) OVER (ORDER BY order_date ROWS UNBOUNDED PRECEDING)
  / SUM(total) OVER () AS cumulative_share

Two windows in one expression — the running total over the grand total, which is how you build a Pareto chart.

Key points
  • ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW is the running-total frame
  • PARTITION BY resets the cumulative sum per group
  • The first rows of a moving average cover fewer periods
Check yourself