Window functions perform calculations across sets of rows related to the current row without collapsing the result set.
Window functions calculate aggregates, rankings, and running totals over a defined window of rows while preserving individual rows. They rely on the OVER() clause to specify PARTITION BY and ORDER BY scopes.
Use GROUP BY to collapse rows into single results.Use window functions when you need row-level detail alongside aggregated insights—e.g., each order with its customer’s lifetime spend.
Add ROWS BETWEEN or RANGE BETWEEN in the OVER() clause.Default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW for cumulative calculations.
Ranking (ROW_NUMBER, RANK, DENSE_RANK), aggregates (SUM, AVG, COUNT), distribution (PERCENT_RANK), navigation (LAG, LEAD), and analytics (NTILE) all accept OVER().
SELECT c.id,
c.name,
SUM(o.total_amount) AS customer_total,
RANK() OVER(ORDER BY SUM(o.total_amount) DESC) AS spend_rank
FROM Orders o JOIN Customers c ON c.id = o.customer_id
GROUP BY c.id, c.name;
SELECT order_date,
SUM(total_amount) AS day_total,
AVG(SUM(total_amount)) OVER(ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS ma_7d
FROM Orders
GROUP BY order_date
ORDER BY order_date;
1.Always PARTITION BY the smallest set that satisfies the calculation to avoid excess scanning.
2. Use ORDER BY only when ordering affects the result (e.g., running totals).
3. Persist heavy window queries into temporary tables for downstream joins.
• Customer lifetime value
• Order sequence numbers per customer
• Stock level deltas
• Cohort retention metrics
.
No. Use a subquery or QUALIFY to filter by window results.
They scan more data than simple aggregates. Limit partitions, create clustering keys, and persist heavy results when possible.
Snowflake computes them on the fly during query execution; results are not stored unless you SELECT INTO or CREATE TABLE AS.