How to Use ROW_NUMBER in PostgreSQL

Galaxy Glossary

How do I assign row numbers to query results in PostgreSQL?

ROW_NUMBER returns a sequential integer for each row in a result set based on the ORDER BY of a window.

Sign up for the latest in SQL knowledge from the Galaxy Team!
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.

Description

What does ROW_NUMBER do?

ROW_NUMBER() assigns a unique, sequential integer to each row returned by a query. Numbers restart only when PARTITION BY is specified; otherwise, numbering is global.

When should I use ROW_NUMBER()?

Use it to paginate results, pick the first row per group, de-duplicate data, or build rankings without adding surrogate keys.

How do I write the basic syntax?

Call ROW_NUMBER() OVER(ORDER BY column) in the SELECT list.Always include ORDER BY inside OVER to guarantee consistent numbering.

How can I restart numbering per group?

Add PARTITION BY group_column inside the OVER clause. Each partition starts at 1, letting you rank rows within categories like customers or products.

How do I filter to the first row in each group?

Wrap the query using a CTE or sub-query, then filter on WHERE row_num = 1.This keeps only the top-ranked row per partition.

Example: pick each customer’s latest order

This query numbers orders per customer by order_date DESC, then selects row_num = 1 to get the most recent order per customer.

Best practices for ROW_NUMBER()

1) Always ORDER BY deterministic columns.
2) Prefer PARTITION BY when grouping.
3) Index the ORDER BY columns for large datasets.

What are common mistakes?

1) Omitting ORDER BY causes non-deterministic numbering.
2) Confusing FILTER clause with PARTITION BY; they serve different purposes.

See also

DENSE_RANK(), RANK(), NTILE(), LIMIT/OFFSET for pagination.

.

Why How to Use ROW_NUMBER in PostgreSQL is important

How to Use ROW_NUMBER in PostgreSQL Example Usage


WITH numbered AS (
    SELECT
        o.id,
        o.customer_id,
        o.order_date,
        o.total_amount,
        ROW_NUMBER() OVER (
            PARTITION BY o.customer_id
            ORDER BY o.order_date DESC
        ) AS row_num
    FROM Orders o
)
SELECT *
FROM numbered
WHERE row_num = 1;

How to Use ROW_NUMBER in PostgreSQL Syntax


SELECT
    ROW_NUMBER() OVER (
        [PARTITION BY partition_expression]
        ORDER BY sort_expression [ASC|DESC]
    ) AS row_num,
    other_columns
FROM table_name;

-- Ecommerce example: rank newest orders per customer
SELECT
    id,
    customer_id,
    order_date,
    ROW_NUMBER() OVER (
        PARTITION BY customer_id
        ORDER BY order_date DESC
    ) AS row_num
FROM Orders;

Common Mistakes

Frequently Asked Questions (FAQs)

Does ROW_NUMBER require a unique ORDER BY?

No, but using non-unique columns can result in ties. Add more columns to ORDER BY for a stable order.

Is ROW_NUMBER() slower than LIMIT/OFFSET for pagination?

ROW_NUMBER() can be faster on large offsets because it avoids counting skipped rows, especially when paired with indexed ORDER BY columns.

Can I update a table with ROW_NUMBER?

Yes. Use a sub-query or CTE that computes row numbers, then update or delete using the row_num in a WHERE clause.

Want to learn about other SQL terms?

Trusted by top engineers on high-velocity teams
Aryeo Logo
Assort Health
Curri
Rubie
BauHealth Logo
Truvideo Logo
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.