ROW_NUMBER() assigns a unique, sequential integer to each row within a partition ordered by a specified column list.
ROW_NUMBER() is a window function that returns a monotonically increasing integer starting at 1 for the first row in each partition. It is useful for de-duplicating records, implementing pagination, and selecting the first or last row per group without complex subqueries.
Use ROW_NUMBER() OVER (PARTITION BY partition_cols ORDER BY sort_cols) AS alias. PARTITION BY is optional; ORDER BY is required to guarantee deterministic numbering.
The example below numbers all orders by descending total_amount so the highest value order receives row number 1.
SELECT
id,
customer_id,
total_amount,
ROW_NUMBER() OVER (ORDER BY total_amount DESC) AS rn
FROM Orders;
Partition by customer_id and order by order_date DESC, then filter for rn = 1.
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn
FROM Orders)
SELECT *
FROM ranked
WHERE rn = 1;
Wrap the query with ROW_NUMBER(), then filter by a range of row numbers.
WITH ordered AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY created_at DESC) AS rn
FROM Customers)
SELECT *
FROM ordered
WHERE rn BETWEEN 101 AND 150;
Always include ORDER BY for deterministic results; use PARTITION BY to restart numbering per group; avoid using ROW_NUMBER() without a WHERE filter in very large tables to minimize unnecessary scans.
See below for two frequent errors and their fixes.
Yes. Provide a comma-separated list in the ORDER BY clause, e.g., ORDER BY order_date DESC, id.
Minimal overhead when the ORDER BY column is in sort key or distribution key. Large unsorted tables may require extra disk spill during sorting.
ROW_NUMBER() returns unique integers without gaps; RANK() assigns the same rank to ties and can skip numbers after ties.