All posts
6 min read · 2026-04-22

Window functions explained visually

window-functions
fundamentals

A window function computes a value across a set of rows related to the current row, without collapsing them like GROUP BY does. Three knobs: PARTITION BY (which rows count), ORDER BY (the sequence), and frame (how far back/forward).

PARTITION BY = group, but keep all rows

PARTITION BY customer_id splits the input into per-customer windows. Unlike GROUP BY, you still get every row out.

ORDER BY inside OVER = the sequence within the window

Required for ROW_NUMBER and any cumulative frame. Without it, frames default to all rows in the partition.

ROW_NUMBER vs RANK vs DENSE_RANK

  • ROW_NUMBER: 1, 2, 3, 4 — ties broken arbitrarily.
  • RANK: 1, 2, 2, 4 — ties share a rank, next rank skips.
  • DENSE_RANK: 1, 2, 2, 3 — ties share, next rank does not skip.
SELECT
  customer_id,
  ordered_at,
  ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS visit_number
FROM orders;

Lineage tools track window expressions as derived projections of their input columns — see the running-total example for a worked walkthrough.

Try it on your own SQL:

Related