OVER clause
The OVER clause turns an aggregate or ranking function into a window function by defining the partition, order, and frame it operates on, without collapsing the result set.
Overview
The OVER clause is what distinguishes a window function from a regular aggregate function. Adding OVER (...) after a function like SUM(), AVG(), or ROW_NUMBER() tells the engine to compute the value per row over a defined "window" of related rows, rather than collapsing all rows into one.
Copy code
SELECT
order_id,
customer_id,
revenue,
SUM(revenue) OVER (PARTITION BY customer_id ORDER BY order_date) AS running_total
FROM orders;
The OVER clause has three optional pieces:
PARTITION BY— which rows belong together.ORDER BY— how rows are ordered within a partition (required for ranking functions and frames).- A frame clause (
ROWS/RANGE/GROUPS BETWEEN ...) — which rows within the ordered partition are included.
An empty OVER () applies the function across the entire result set as one partition.
Named windows
When several window functions in a query share the same partition/order/frame, standard SQL lets you define a named window once with a WINDOW clause and reference it by name:
Copy code
SELECT
customer_id, order_date, revenue,
SUM(revenue) OVER w AS running_total,
AVG(revenue) OVER w AS running_avg
FROM orders
WINDOW w AS (PARTITION BY customer_id ORDER BY order_date);
DuckDB specifics
DuckDB supports the full OVER clause syntax, named WINDOW definitions, and the EXCLUDE frame modifier. It also supports QUALIFY, which filters rows based on a window function's output — the natural complement to OVER, since WHERE cannot reference window function results directly:
Copy code
SELECT customer_id, revenue, SUM(revenue) OVER w AS running_total
FROM orders
WINDOW w AS (PARTITION BY customer_id ORDER BY order_date)
QUALIFY running_total > 10000;
Related terms
A window frame is the subset of rows within a window function's partition that a calculation is applied to, defined with ROWS, RANGE, or GROUPS relative to the current row.
window functions →Window functions allow you to perform calculations across a set of table rows that are somehow related to the current row, similar to aggregate functions,…
PARTITION BY →PARTITION BY divides rows into independent groups for a window function or an output operation, so calculations reset for each group without collapsing rows the way GROUP BY does.
QUALIFY →QUALIFY filters rows based on the result of a window function, letting you write conditions like 'keep only the top-ranked row per group' without wrapping the query in a subquery.
ROW_NUMBER →ROW_NUMBER() is a SQL window function that assigns a unique, sequential integer to each row within a partition based on a specified order, with no ties.
FILTER clause →The FILTER clause restricts which rows an aggregate function processes, letting you compute multiple conditional aggregates in a single GROUP BY query without CASE expressions.
FAQS
WHERE is evaluated before window functions are computed, so the window function's output doesn't exist yet at that stage. Use a subquery/CTE with an outer WHERE, or DuckDB's QUALIFY clause, to filter on window function results.
