Chapter 21: PostgreSQL ORDER BY

Part 1: What is ORDER BY?

The ORDER BY clause sorts the result set of a query by one or more columns, in ascending or descending order. It’s the last step in query execution (conceptually), organizing your data after it’s been filtered and grouped.

The Basic Syntax

sql

  • ASC – Ascending order (smallest to largest, A to Z) – this is the default

  • DESC – Descending order (largest to smallest, Z to A)

Part 2: Setting Up Our Example Data

Let’s create a rich dataset to explore all the sorting possibilities. We’ll create an online bookstore database:

sql

Part 3: Basic Sorting – Single Column

1. Ascending Order (Default)

When you don’t specify a direction, PostgreSQL assumes ASC (ascending):

sql

Result:

title price
Pride and Prejudice 9.99
Incomplete Records 9.99
The Catcher in the Rye 12.99
Le Petit Prince 12.99
1984 13.99
Brave New World 13.99
The Help 13.99
The Hobbit 14.99
To Kill a Mockingbird 14.99
The Hunger Games 14.99

Notice how NULL prices are excluded because we used WHERE price IS NOT NULL. Without that, NULLs would appear at the end (we’ll discuss NULL sorting later).

2. Descending Order

Use DESC to sort from highest to lowest:

sql

Result:

title price
Becoming 32.50
Educated 27.99
Where the Crawdads Sing 26.99
The Midnight Library 25.99
Sapiens 24.99
The Silent Patient 24.99
Atomic Habits 21.99
Cien años de soledad 18.99
Dune 18.99
The Da Vinci Code 16.99

3. Sorting Text (Alphabetical)

Text sorting follows alphabetical order (based on the database’s collation):

sql

Result:

title
1984
Atomic Habits
Becoming
Brave New World
Cien años de soledad
Dune
Educated
Gone Girl
Incomplete Records
Le Petit Prince

Notice that numbers come before letters in ASCII sorting, so “1984” appears first.

4. Sorting by Date

Dates sort chronologically – older dates first in ascending order:

sql

Result:

title publication_date
Pride and Prejudice 1813-01-28
The Great Gatsby 1925-04-10
Brave New World 1932-01-01
The Hobbit 1937-09-21
Le Petit Prince 1943-04-06
1984 1949-06-08
The Catcher in the Rye 1951-07-16
To Kill a Mockingbird 1960-07-11
Dune 1965-08-01
Cien años de soledad 1967-05-30
sql

Result:

title publication_date
Mystery Book 2020-01-01
The Midnight Library 2020-08-13
The Silent Patient 2019-02-05
Where the Crawdads Sing 2018-08-14
Becoming 2018-11-13
Atomic Habits 2018-10-16
Educated 2018-02-20
Gone Girl 2012-05-24
Sapiens 2011-01-01
The Help 2009-02-10

Part 4: Multi-Column Sorting

This is where ORDER BY becomes truly powerful. You can sort by multiple columns, with each column having its own sort direction.

1. Primary and Secondary Sorting

Sort by genre first, then by price within each genre:

sql

Result (partial):

genre title price
Biography Becoming 32.50
Biography Educated 27.99
Children Le Petit Prince 12.99
Fantasy The Hobbit 14.99
Fiction Where the Crawdads Sing 26.99
Fiction The Midnight Library 25.99
Fiction The Alchemist 15.99
Fiction To Kill a Mockingbird 14.99
Fiction The Help 13.99
Fiction The Great Gatsby 11.99

Notice how:

  • All Biography books come first (alphabetically)

  • Within Biography, books are sorted by price descending

  • Then Children’s books, then Fantasy, etc.

2. Different Directions for Different Columns

You can mix ASC and DESC for different columns:

sql

Result:

genre title publication_date
Biography Becoming 2018-11-13
Biography Educated 2018-02-20
Children Le Petit Prince 1943-04-06
Fantasy The Hobbit 1937-09-21
Fiction The Midnight Library 2020-08-13
Fiction Where the Crawdads Sing 2018-08-14
Fiction The Help 2009-02-10
Fiction The Alchemist 1988-01-01
Fiction To Kill a Mockingbird 1960-07-11
Fiction The Catcher in the Rye 1951-07-16

3. Using Column Position (Not Recommended)

Instead of column names, you can use numbers representing column positions in the SELECT list:

sql

⚠️ Warning: This is fragile! If you change the SELECT list order, your sorting breaks. Always prefer explicit column names for clarity and maintainability.

Part 5: Sorting with NULL Values

NULL values present a special challenge in sorting. Where should they appear? PostgreSQL gives you control.

1. Default NULL Behavior

By default, NULLs are considered larger than any non-NULL value:

sql

Result (with NULLs at the end):

title price
Pride and Prejudice 9.99
Incomplete Records 9.99
… (non-NULL values) …
Mystery Book NULL

In descending order, NULLs appear at the beginning:

sql

Result:

title price
Mystery Book NULL
Becoming 32.50
Educated 27.99

2. Controlling NULL Placement with NULLS FIRST/LAST

PostgreSQL provides special clauses to control NULL positioning:

sql

This is incredibly useful when you want to see missing values prominently or hide them at the end.

3. Practical Example: Inventory Report

sql

Result:

title price in_stock
Mystery Book NULL false
Pride and Prejudice 9.99 true
Incomplete Records 9.99 true

Part 6: Sorting by Expressions

You’re not limited to column names – you can sort by any expression.

1. Sorting by Calculated Values

sql

2. Sorting by String Functions

sql

Result:

title title_length
Pride and Prejudice 20
Where the Crawdads Sing 24
To Kill a Mockingbird 22
The Catcher in the Rye 21
The Da Vinci Code 16

3. Sorting by Case-Insensitive Text

sql

4. Complex Expressions

sql

Result:

title rating sold_copies popularity_score
The Hobbit 4.8 100000000 480000000.0
Le Petit Prince 4.9 200000000 980000000.0
The Alchemist 4.6 65000000 299000000.0
The Da Vinci Code 4.1 80000000 328000000.0

Part 7: Sorting with CASE Statements

For complex, conditional sorting logic, you can use CASE inside ORDER BY.

1. Custom Sort Order

Sort genres in a custom order, not alphabetical:

sql

Result:

genre sort_order
Fiction 1
Science Fiction 2
Fantasy 3
Thriller 4
Biography 5
Children 5
History 5

2. Priority Sorting

Show in-stock items first, then sort by price:

sql

Result:

title in_stock price
Pride and Prejudice true 9.99
Le Petit Prince true 12.99
1984 true 13.99
The Catcher in the Rye false 12.99
The Da Vinci Code false 16.99

All in-stock items appear first (sorted by price), followed by out-of-stock items.

3. Multi-Tier Priority

sql

Part 8: Random Sorting

Sometimes you want random order – for features like “random book recommendation”:

sql

Each time you run this, you get a different set of 5 books.

Performance Note: ORDER BY RANDOM() on large tables can be slow because it must assign a random number to every row and then sort. For large datasets, consider alternative approaches.

Part 9: Sorting with DISTINCT

When using SELECT DISTINCT, sorting becomes particularly important:

sql

Note: The columns in ORDER BY must appear in the SELECT list when using DISTINCT:

sql

PostgreSQL is more permissive, but for portability, include all ORDER BY columns in SELECT when using DISTINCT.

Part 10: Sorting with GROUP BY and Aggregate Functions

When grouping data, you often want to sort by the aggregated results:

1. Sort by Count

sql

Result:

genre book_count avg_price
Fiction 7 15.99
Science Fiction 3 15.66
Thriller 3 19.32
Biography 2 30.25

2. Sort by Aggregate

sql

3. Multiple Aggregates

sql

Part 11: Real-World Examples

Example 1: E-commerce Product Listing

sql

Example 2: Bestseller List

sql

Example 3: Recently Published, Highly Rated Books

sql

Example 4: Inventory Value Report

sql

Example 5: Customer Orders Analysis

Let’s create an orders table for more examples:

sql

Part 12: Performance Considerations

1. Indexes for Sorting

Indexes can dramatically speed up ORDER BY operations:

sql

2. When Indexes Help

sql

3. LIMIT and Sorting

When combining ORDER BY with LIMIT, PostgreSQL can optimize by only sorting enough rows to satisfy the LIMIT:

sql

4. Sorting Large Datasets

For very large tables, consider:

  • Creating appropriate indexes

  • Using approximate techniques when exact order isn’t critical

  • Partitioning tables

  • Materialized views for frequently-used sorted results

Part 13: Advanced Sorting Techniques

1. Sorting by JSON Fields

If you have JSON data, you can sort by specific keys:

sql

2. Natural Sort (Human-Friendly Sorting)

For strings with numbers, natural sorting often makes more sense:

sql

3. Collation-Specific Sorting

Different languages sort differently:

sql

Part 14: Common Mistakes and How to Avoid Them

Mistake 1: Forgetting ORDER BY Altogether

sql

Mistake 2: Mixing ASC/DESC Incorrectly

sql

Each column gets its own direction specification.

Mistake 3: Using Column Aliases Incorrectly

sql

Mistake 4: Sorting by Large Text Columns

sql

Mistake 5: Not Understanding NULL Behavior

sql

Summary: The ORDER BY Philosophy

ORDER BY transforms raw data into meaningful information by revealing patterns, rankings, and relationships:

  1. Basic sorting – Single column, ASC/DESC

  2. Multi-level sorting – Primary, secondary, tertiary criteria

  3. Expression sorting – Sort by calculated values

  4. Conditional sorting – Custom logic with CASE

  5. NULL handling – Control where missing values appear

  6. Performance awareness – Indexes and query optimization

Remember the query execution order:

  1. FROM (get tables)

  2. WHERE (filter rows)

  3. GROUP BY (group rows)

  4. HAVING (filter groups)

  5. SELECT (compute expressions)

  6. ORDER BY (sort results) – HERE!

  7. LIMIT (limit output)

This means ORDER BY works on the final result set, after all filtering and grouping. It’s the last step before LIMIT, which is why LIMIT can be optimized with sorted results.

Key takeaways:

  • Always specify ORDER BY when row order matters – never rely on default order

  • Use DESC for highest-to-lowest, ASC for lowest-to-highest

  • Multi-column sorting is powerful – think of it as “then by” logic

  • Control NULL placement explicitly with NULLS FIRST/LAST

  • Index columns you frequently sort by

  • Test with EXPLAIN to see if your sorts are efficient

The ORDER BY clause turns your database results from random piles of data into organized, meaningful information. Whether you’re building a user-facing product catalog, generating reports, or analyzing trends, mastering ORDER BY is essential for presenting data in its most useful form.

Would you like me to elaborate on any specific aspect of ORDER BY, such as more complex sorting scenarios, performance optimization, or integration with other SQL features?

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *