Running total

A windowed SUM keeps row-level detail while accumulating — the simplest window function to start with.

Edit this pageReport an issue

Syntax

SUM(expression) OVER (
  [PARTITION BY partition_expression, ...]
  ORDER BY sort_expression [ASC | DESC], ...
)
ParameterTypeNotes
ORDER BY*expression [ASC|DESC], …

Defines the accumulation order. With an ORDER BY and no explicit frame, the window defaults to "start of partition through the current row" — which is exactly a running total.

PARTITION BYexpression, …

Optional. Restarts the total per group instead of running across everything.

What it does

SQL playground
Loading editor…
⌘/Ctrl + Enter

Each row keeps its own revenue, but running_total is the sum of every row up to and including it. This is the core difference from GROUP BY, which would collapse the months into a single summed row.

Per group

SQL playground
Loading editor…
⌘/Ctrl + Enter

PARTITION BY customer_id resets the accumulation at each customer boundary instead of running across the whole table.

Gotchas

  • This is the default frame, not a special case. Any ORDER BY inside OVER (…) without an explicit ROWS/RANGE clause behaves this way — see window frames for what changes if you add one.
  • Ties in ORDER BY are included together as one step under the default RANGE frame — two same-day orders both get the post-both total, not two different intermediate values.
  • Without PARTITION BY, the total runs across the entire result set — easy to do by accident when you meant to reset it per group.
  • Window frames — ROWS vs RANGE, and why the default frame behaves this way.
  • Running totals & moving averages — moving averages, percent-of-total, and month-over-month change built on the same idea.
  • LAG / LEAD — comparing to one specific prior row instead of accumulating all of them.

Safety check before shipping

  • confirm the ordering is intentional and deterministic
  • decide whether the total should reset per group (add PARTITION BY) or run across the full set
  • check how ties in the ORDER BY column are meant to behave
Was this page helpful?

On this page