SELECT order_id,
customer_id,
COUNT(*) OVER () AS total_rows
FROM orders;A window aggregate keeps detail rows intact while computing a value across the full result set.
Core window function syntax, partitions, ordering, and frame clauses for analytic SQL queries.
Start with the smallest patterns that make window functions click.
SELECT order_id,
customer_id,
COUNT(*) OVER () AS total_rows
FROM orders;A window aggregate keeps detail rows intact while computing a value across the full result set.
SELECT order_id,
customer_id,
amount,
SUM(amount) OVER (PARTITION BY customer_id) AS customer_total
FROM orders;`PARTITION BY` resets the calculation for each logical group.
Number rows in order within each customer.
SELECT order_id,
customer_id,
created_at,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY created_at DESC
) AS rn
FROM orders;`ORDER BY` inside the window defines sequence for ranking and frame-aware calculations.
SELECT order_id,
amount,
SUM(amount) OVER w AS running_sum,
AVG(amount) OVER w AS running_avg
FROM orders
WINDOW w AS (
PARTITION BY customer_id
ORDER BY created_at
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
);Named windows improve readability when several expressions share the same partition, order, and frame.
SELECT created_at,
amount,
SUM(amount) OVER (
ORDER BY created_at
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM orders;Use `ROWS` when you want frame boundaries to follow row positions rather than peer groups.
SELECT score,
COUNT(*) OVER (
ORDER BY score
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_count
FROM exam_results;`RANGE` can treat rows with equal sort values as peers, which often changes cumulative results compared with `ROWS`.
Compare a row against all earlier rows only.
SELECT created_at,
amount,
AVG(amount) OVER (
ORDER BY created_at
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) AS avg_before_current
FROM orders;This pattern is useful when you need a historical benchmark without including the current row in the average.
Quick examples of common frame shapes.
ROWS BETWEEN CURRENT ROW AND CURRENT ROWUseful in examples and to contrast with broader frames.
ROWS BETWEEN 6 PRECEDING AND CURRENT ROWA classic moving window for row-based smoothing.
ROWS BETWEEN CURRENT ROW AND 3 FOLLOWINGHandy for queueing, forecast windows, or lead-like summaries.
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGFor some functions, this makes intent explicit and avoids dialect-specific defaults.