ORDER BY

ORDER BY explained with practical SQL patterns, edge cases, and production-ready guidance.

5 min read · Last updated: March 2026 · Back to overview

Quick Answer

The ORDER BY clause sorts rows returned by a SELECT statement in ascending (ASC) or descending (DESC) order based on one or more columns or expressions. Without ORDER BY, PostgreSQL returns rows in an unspecified order.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

Introduction to PostgreSQL ORDER BY

When you run a SELECT query, PostgreSQL does not guarantee any particular row order unless you specify one. The ORDER BY clause controls how the result set is sorted before it is returned to the client.

The basic syntax is:

SELECT select_list
FROM table_name
ORDER BY sort_expression1 [ASC | DESC],
         sort_expression2 [ASC | DESC],
         ...;

ASC (ascending) is the default direction — you can omit it if ascending order is what you want. DESC reverses the sort to descending.

ORDER BY examples

These examples use the customer table from the standard DVD rental sample database.

Sort by one column ascending:

SELECT first_name, last_name
FROM customer
ORDER BY first_name ASC;

Because ASC is the default, you can also write it as:

SELECT first_name, last_name
FROM customer
ORDER BY first_name;

Sort by one column descending:

SELECT first_name, last_name
FROM customer
ORDER BY last_name DESC;

Sort by multiple columns:

PostgreSQL applies the sort expressions from left to right. Rows are first sorted by first_name ascending, then within rows that share the same first name, by last_name descending:

SELECT first_name, last_name
FROM customer
ORDER BY first_name ASC, last_name DESC;

Sort by an expression or alias:

Because ORDER BY is evaluated after SELECT, you can reference column aliases defined in the select list:

SELECT first_name, LENGTH(first_name) AS name_len
FROM customer
ORDER BY name_len DESC;

This returns customers sorted from longest to shortest first name.

Handling NULL values in ORDER BY

NULL represents unknown data. By default, PostgreSQL places NULLs last when sorting ascending and first when sorting descending. You can override this with NULLS FIRST or NULLS LAST:

-- Ascending, NULLs last (the default)
SELECT num FROM sort_demo ORDER BY num ASC NULLS LAST;

-- Ascending, NULLs first (override)
SELECT num FROM sort_demo ORDER BY num ASC NULLS FIRST;

-- Descending, NULLs last (override)
SELECT num FROM sort_demo ORDER BY num DESC NULLS LAST;

Example output for ascending with NULLS LAST:

num
-----
  1
  2
  3
null
(4 rows)

Tips for using ORDER BY effectively

  • Always include ORDER BY when using LIMIT or OFFSET — without it, the rows you receive are unpredictable because PostgreSQL may return them in any order.
  • You can sort by a column that is not in the select list, as long as it is accessible from the FROM clause.
  • Sorting large result sets can be expensive. An index on the sort column lets PostgreSQL avoid a full sort by scanning the index in order.
  • For pagination, combine ORDER BY with LIMIT and OFFSET, or use keyset pagination (comparing against the last seen value) for better performance on large offsets.

Reference: PostgreSQL documentation — SELECT / ORDER BY.

Continue in Querying Data: SELECT DISTINCT.

Related in this section: PostgreSQL SELECT · Column Aliases · SELECT DISTINCT

Frequently Asked Questions

What is the default sort order in PostgreSQL ORDER BY?

The default is ASC (ascending), so ORDER BY column_name and ORDER BY column_name ASC are identical. For text, ascending means alphabetical (A–Z). For numbers, it means smallest to largest. For dates, it means earliest to latest.

Can I sort by a column that is not in the SELECT list?

Yes. ORDER BY can reference any column available in the FROM clause, even if it does not appear in the select list. For example: SELECT first_name FROM customer ORDER BY last_name; — this sorts by last_name without displaying it.

How does PostgreSQL ORDER BY handle NULL values?

By default, NULLs sort last in ascending order and first in descending order. You can control this explicitly with NULLS FIRST or NULLS LAST: ORDER BY column ASC NULLS FIRST puts NULLs at the top even when sorting ascending.

Can I use ORDER BY with column position numbers instead of column names?

Yes, PostgreSQL allows ORDER BY 1, 2 to sort by the first and second columns in the select list. However, this is fragile — if you reorder the SELECT columns the sort changes silently. Prefer explicit column names or aliases for maintainability.

Does adding ORDER BY slow down my query?

Sorting has a cost, especially on large result sets. PostgreSQL performs an in-memory sort if the result fits in work_mem, and spills to disk otherwise. An index on the sort column can eliminate the sort step entirely — check EXPLAIN output for "Sort" vs "Index Scan" nodes to see whether an index is being used.