A SQL window function performs a calculation across a set of table rows that are related to the current row without collapsing the result set. Use the OVER() clause to define the window’s scope and ordering, then apply ranking, aggregation, or analytic functions—like ROW_NUMBER(), SUM(), or LAG()—to analyze data side-by-side with original rows.
SQL window functions compute values across a related set of rows—called a window—while preserving each row in the output. They rely on the OVER()
clause to define how rows are partitioned and ordered.
The OVER()
clause first partitions rows with PARTITION BY
and then sorts each partition with ORDER BY
. If neither is supplied, the window is the entire result set.
GROUP BY
aggregates rows into a single summary per group, removing detail. Window functions keep every row, adding analytic columns side-by-side so you can filter or join on original data.
Aggregation functions (SUM, AVG, COUNT), ranking functions (ROW_NUMBER, RANK, DENSE_RANK), and analytic functions (LAG, LEAD, FIRST_VALUE) all support OVER()
.
PARTITION BY
groups rows into independent windows, such as per customer or per month. Calculations reset when the partition changes.
ORDER BY
defines the row order inside each partition, enabling running totals, moving averages, and rank calculations.
The frame clause (e.g., ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) narrows the rows considered for each calculation, ideal for rolling sums and averages.
Use ROW_NUMBER()
with a window to assign a unique sequential index within each partition, often for deduplicating or top-N reports.
LAG()
fetches a prior row’s value; LEAD()
fetches a future row’s value. Both make period-over-period analysis straightforward.
Typical scenarios include running totals, year-over-year growth, user funnel step ranking, deduplication, and time-series comparisons.
By combining raw detail with analytic outputs in one result set, window functions reduce subqueries, simplify joins, and speed up exploratory analysis.
Window functions may trigger extra sorting. Index partitions and order columns, minimize frame sizes, and avoid huge unpartitioned windows to improve speed.
Always specify PARTITION BY
and ORDER BY
when logical. Keep frame clauses explicit, use CTEs for readability, and test performance on sample data before production.
Window functions add powerful analytic columns without losing row detail. Master OVER()
, choose the right function, and tune partitions and frames for fast, insightful queries.
Yes. PostgreSQL has full support. MySQL added window functions in version 8.0. Check version compatibility for your database.
They require extra sorting but often replace multiple joins or subqueries, netting similar or better performance. Proper indexing helps.
You can reference a window function result in an outer query, but not directly inside another window function in the same SELECT list.
RANK() leaves gaps after ties (1,1,3), while DENSE_RANK() assigns consecutive ranks (1,1,2).