SQL ROW_NUMBER assigns a unique, sequential integer to each row within a result-set partition, ordered by a specified column list.
ROW_NUMBER is a window function that returns a sequential integer, starting at 1, to each row in a result set. Numbers restart when a PARTITION BY clause is present. Because ranking happens after the FROM, WHERE, and GROUP BY stages, ROW_NUMBER can reference aggregated or joined columns.
ROW_NUMBER syntax is ANSI-SQL and works in PostgreSQL, SQL Server, Snowflake, BigQuery, Redshift, and Oracle. You write ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...)
. If PARTITION BY is omitted, the numbering spans the entire query result.
ROW_NUMBER eliminates self-joins and subqueries when deduplicating, paginating results, or selecting the first/last row per group. It improves readability and often boosts performance compared to correlated subqueries.
Place the function in the SELECT list, define ORDER BY for deterministic numbering, and optionally partition.SELECT
user_id,
created_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
FROM events;
Add a PARTITION BY clause listing columns that define each group. The sequence restarts at 1 for every distinct combination, letting you rank rows within categories like customer, date, or region.
Wrap the ROW_NUMBER query in a CTE or subquery, then filter on the generated column.WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY total DESC) AS rn
FROM orders)
SELECT *
FROM ranked
WHERE rn <= 3;
Generate ROW_NUMBER ordered by the field that defines “most recent” or “preferred.” Delete or ignore rows where rn > 1, keeping a single record per key.
Always include deterministic columns in ORDER BY to avoid non-repeatable ranks. Use indexes on ORDER BY fields for large tables. In OLTP systems, run ROW_NUMBER in read replicas to offload work.
Forgetting ORDER BY causes arbitrary numbering. Using ROW_NUMBER instead of RANK or DENSE_RANK when ties matter yields missing ranks. Filtering on ROW_NUMBER in the same SELECT without a subquery can fail in some dialects.
ROW_NUMBER simplifies complex ranking logic into a single, readable clause, reducing query length and execution time. Because it is ANSI-standard, knowledge transfers across platforms, making engineers more versatile. In analytics pipelines, ROW_NUMBER is the go-to tool for de-duping event streams and building slowly changing dimensions without procedural code. ROW_NUMBER also underpins pagination in APIs and dashboards, letting developers return consistent slices of large datasets. Mastery of ROW_NUMBER therefore accelerates both backend engineering and user-facing analytics.
No. RANK creates gaps after ties, DENSE_RANK keeps ranks contiguous, and ROW_NUMBER assigns a unique value even when rows tie.
Yes. Number all rows, then filter for a numeric range—for example, rows 51–100. This works in any database supporting ROW_NUMBER.
Galaxy’s AI copilot autocompletes the OVER clause, suggests correct ORDER BY columns, and previews the numbered result, speeding up query writing.
ROW_NUMBER requires sorting. Indexes on ORDER BY columns and partition pruning keep the operation efficient even on large datasets.