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
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token keyword">SELECT</span> column1<span class="token punctuation">,</span> column2<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token keyword">FROM</span> table_name <span class="token punctuation">[</span><span class="token keyword">WHERE</span> condition<span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token keyword">GROUP</span> <span class="token keyword">BY</span> <span class="token keyword">column</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token keyword">HAVING</span> condition<span class="token punctuation">]</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> column1 <span class="token punctuation">[</span><span class="token keyword">ASC</span> <span class="token operator">|</span> <span class="token keyword">DESC</span><span class="token punctuation">]</span><span class="token punctuation">,</span> column2 <span class="token punctuation">[</span><span class="token keyword">ASC</span> <span class="token operator">|</span> <span class="token keyword">DESC</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">;</span> |
-
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<span class="token comment">-- Create a comprehensive books table</span> <span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> books <span class="token punctuation">(</span> book_id <span class="token keyword">SERIAL</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span><span class="token punctuation">,</span> title <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">,</span> author <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span> genre <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">,</span> price <span class="token keyword">DECIMAL</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> pages <span class="token keyword">INTEGER</span><span class="token punctuation">,</span> publication_date <span class="token keyword">DATE</span><span class="token punctuation">,</span> in_stock <span class="token keyword">BOOLEAN</span><span class="token punctuation">,</span> rating <span class="token keyword">DECIMAL</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> sold_copies <span class="token keyword">INTEGER</span><span class="token punctuation">,</span> <span class="token keyword">language</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">-- Insert diverse sample data</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> books <span class="token punctuation">(</span>title<span class="token punctuation">,</span> author<span class="token punctuation">,</span> genre<span class="token punctuation">,</span> price<span class="token punctuation">,</span> pages<span class="token punctuation">,</span> publication_date<span class="token punctuation">,</span> in_stock<span class="token punctuation">,</span> rating<span class="token punctuation">,</span> sold_copies<span class="token punctuation">,</span> <span class="token keyword">language</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'The Silent Patient'</span><span class="token punctuation">,</span> <span class="token string">'Alex Michaelides'</span><span class="token punctuation">,</span> <span class="token string">'Thriller'</span><span class="token punctuation">,</span> <span class="token number">24.99</span><span class="token punctuation">,</span> <span class="token number">336</span><span class="token punctuation">,</span> <span class="token string">'2019-02-05'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.5</span><span class="token punctuation">,</span> <span class="token number">1500000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Where the Crawdads Sing'</span><span class="token punctuation">,</span> <span class="token string">'Delia Owens'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">26.99</span><span class="token punctuation">,</span> <span class="token number">384</span><span class="token punctuation">,</span> <span class="token string">'2018-08-14'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.8</span><span class="token punctuation">,</span> <span class="token number">12000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Becoming'</span><span class="token punctuation">,</span> <span class="token string">'Michelle Obama'</span><span class="token punctuation">,</span> <span class="token string">'Biography'</span><span class="token punctuation">,</span> <span class="token number">32.50</span><span class="token punctuation">,</span> <span class="token number">448</span><span class="token punctuation">,</span> <span class="token string">'2018-11-13'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.9</span><span class="token punctuation">,</span> <span class="token number">10000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Atomic Habits'</span><span class="token punctuation">,</span> <span class="token string">'James Clear'</span><span class="token punctuation">,</span> <span class="token string">'Self-help'</span><span class="token punctuation">,</span> <span class="token number">21.99</span><span class="token punctuation">,</span> <span class="token number">320</span><span class="token punctuation">,</span> <span class="token string">'2018-10-16'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.9</span><span class="token punctuation">,</span> <span class="token number">8000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Educated'</span><span class="token punctuation">,</span> <span class="token string">'Tara Westover'</span><span class="token punctuation">,</span> <span class="token string">'Biography'</span><span class="token punctuation">,</span> <span class="token number">27.99</span><span class="token punctuation">,</span> <span class="token number">352</span><span class="token punctuation">,</span> <span class="token string">'2018-02-20'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.7</span><span class="token punctuation">,</span> <span class="token number">6000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Midnight Library'</span><span class="token punctuation">,</span> <span class="token string">'Matt Haig'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">25.99</span><span class="token punctuation">,</span> <span class="token number">304</span><span class="token punctuation">,</span> <span class="token string">'2020-08-13'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.3</span><span class="token punctuation">,</span> <span class="token number">3000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Dune'</span><span class="token punctuation">,</span> <span class="token string">'Frank Herbert'</span><span class="token punctuation">,</span> <span class="token string">'Science Fiction'</span><span class="token punctuation">,</span> <span class="token number">18.99</span><span class="token punctuation">,</span> <span class="token number">688</span><span class="token punctuation">,</span> <span class="token string">'1965-08-01'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.7</span><span class="token punctuation">,</span> <span class="token number">20000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Hobbit'</span><span class="token punctuation">,</span> <span class="token string">'J.R.R. Tolkien'</span><span class="token punctuation">,</span> <span class="token string">'Fantasy'</span><span class="token punctuation">,</span> <span class="token number">14.99</span><span class="token punctuation">,</span> <span class="token number">310</span><span class="token punctuation">,</span> <span class="token string">'1937-09-21'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.8</span><span class="token punctuation">,</span> <span class="token number">100000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'1984'</span><span class="token punctuation">,</span> <span class="token string">'George Orwell'</span><span class="token punctuation">,</span> <span class="token string">'Science Fiction'</span><span class="token punctuation">,</span> <span class="token number">13.99</span><span class="token punctuation">,</span> <span class="token number">328</span><span class="token punctuation">,</span> <span class="token string">'1949-06-08'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.6</span><span class="token punctuation">,</span> <span class="token number">30000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Pride and Prejudice'</span><span class="token punctuation">,</span> <span class="token string">'Jane Austen'</span><span class="token punctuation">,</span> <span class="token string">'Romance'</span><span class="token punctuation">,</span> <span class="token number">9.99</span><span class="token punctuation">,</span> <span class="token number">432</span><span class="token punctuation">,</span> <span class="token string">'1813-01-28'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.7</span><span class="token punctuation">,</span> <span class="token number">20000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Catcher in the Rye'</span><span class="token punctuation">,</span> <span class="token string">'J.D. Salinger'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">12.99</span><span class="token punctuation">,</span> <span class="token number">277</span><span class="token punctuation">,</span> <span class="token string">'1951-07-16'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token number">4.0</span><span class="token punctuation">,</span> <span class="token number">65000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'To Kill a Mockingbird'</span><span class="token punctuation">,</span> <span class="token string">'Harper Lee'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">14.99</span><span class="token punctuation">,</span> <span class="token number">281</span><span class="token punctuation">,</span> <span class="token string">'1960-07-11'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.8</span><span class="token punctuation">,</span> <span class="token number">40000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Great Gatsby'</span><span class="token punctuation">,</span> <span class="token string">'F. Scott Fitzgerald'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">11.99</span><span class="token punctuation">,</span> <span class="token number">180</span><span class="token punctuation">,</span> <span class="token string">'1925-04-10'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.5</span><span class="token punctuation">,</span> <span class="token number">25000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Brave New World'</span><span class="token punctuation">,</span> <span class="token string">'Aldous Huxley'</span><span class="token punctuation">,</span> <span class="token string">'Science Fiction'</span><span class="token punctuation">,</span> <span class="token number">13.99</span><span class="token punctuation">,</span> <span class="token number">288</span><span class="token punctuation">,</span> <span class="token string">'1932-01-01'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.4</span><span class="token punctuation">,</span> <span class="token number">15000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Alchemist'</span><span class="token punctuation">,</span> <span class="token string">'Paulo Coelho'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">15.99</span><span class="token punctuation">,</span> <span class="token number">208</span><span class="token punctuation">,</span> <span class="token string">'1988-01-01'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.6</span><span class="token punctuation">,</span> <span class="token number">65000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Sapiens'</span><span class="token punctuation">,</span> <span class="token string">'Yuval Noah Harari'</span><span class="token punctuation">,</span> <span class="token string">'History'</span><span class="token punctuation">,</span> <span class="token number">24.99</span><span class="token punctuation">,</span> <span class="token number">464</span><span class="token punctuation">,</span> <span class="token string">'2011-01-01'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.7</span><span class="token punctuation">,</span> <span class="token number">12000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Da Vinci Code'</span><span class="token punctuation">,</span> <span class="token string">'Dan Brown'</span><span class="token punctuation">,</span> <span class="token string">'Thriller'</span><span class="token punctuation">,</span> <span class="token number">16.99</span><span class="token punctuation">,</span> <span class="token number">592</span><span class="token punctuation">,</span> <span class="token string">'2003-03-18'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token number">4.1</span><span class="token punctuation">,</span> <span class="token number">80000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Hunger Games'</span><span class="token punctuation">,</span> <span class="token string">'Suzanne Collins'</span><span class="token punctuation">,</span> <span class="token string">'Young Adult'</span><span class="token punctuation">,</span> <span class="token number">14.99</span><span class="token punctuation">,</span> <span class="token number">384</span><span class="token punctuation">,</span> <span class="token string">'2008-09-14'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.5</span><span class="token punctuation">,</span> <span class="token number">65000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Gone Girl'</span><span class="token punctuation">,</span> <span class="token string">'Gillian Flynn'</span><span class="token punctuation">,</span> <span class="token string">'Thriller'</span><span class="token punctuation">,</span> <span class="token number">15.99</span><span class="token punctuation">,</span> <span class="token number">432</span><span class="token punctuation">,</span> <span class="token string">'2012-05-24'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.2</span><span class="token punctuation">,</span> <span class="token number">20000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'The Help'</span><span class="token punctuation">,</span> <span class="token string">'Kathryn Stockett'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">13.99</span><span class="token punctuation">,</span> <span class="token number">464</span><span class="token punctuation">,</span> <span class="token string">'2009-02-10'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.7</span><span class="token punctuation">,</span> <span class="token number">15000000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">-- Add some books in other languages</span> <span class="token punctuation">(</span><span class="token string">'Cien años de soledad'</span><span class="token punctuation">,</span> <span class="token string">'Gabriel García Márquez'</span><span class="token punctuation">,</span> <span class="token string">'Fiction'</span><span class="token punctuation">,</span> <span class="token number">18.99</span><span class="token punctuation">,</span> <span class="token number">417</span><span class="token punctuation">,</span> <span class="token string">'1967-05-30'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.9</span><span class="token punctuation">,</span> <span class="token number">50000000</span><span class="token punctuation">,</span> <span class="token string">'Spanish'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Le Petit Prince'</span><span class="token punctuation">,</span> <span class="token string">'Antoine de Saint-Exupéry'</span><span class="token punctuation">,</span> <span class="token string">'Children'</span><span class="token punctuation">,</span> <span class="token number">12.99</span><span class="token punctuation">,</span> <span class="token number">96</span><span class="token punctuation">,</span> <span class="token string">'1943-04-06'</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">4.9</span><span class="token punctuation">,</span> <span class="token number">200000000</span><span class="token punctuation">,</span> <span class="token string">'French'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">-- Add some books with NULL values for demonstration</span> <span class="token punctuation">(</span><span class="token string">'Mystery Book'</span><span class="token punctuation">,</span> <span class="token string">'Unknown Author'</span><span class="token punctuation">,</span> <span class="token string">'Mystery'</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token string">'2020-01-01'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Incomplete Records'</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token number">9.99</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token string">'English'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Part 3: Basic Sorting – Single Column
1. Ascending Order (Default)
When you don’t specify a direction, PostgreSQL assumes ASC (ascending):
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort books by price from cheapest to most expensive</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price<span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort books by price from most expensive to cheapest</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
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):
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token comment">-- Sort books alphabetically by title</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> title <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> title <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token comment">-- Sort books by publication date, oldest first</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> publication_date <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> publication_date <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> publication_date <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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 |
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token comment">-- Sort books by publication date, newest first</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> publication_date <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> publication_date <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> publication_date <span class="token keyword">DESC</span> <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token keyword">SELECT</span> genre<span class="token punctuation">,</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre <span class="token keyword">ASC</span><span class="token punctuation">,</span> price <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort by genre A-Z, and within each genre, by publication date newest first</span> <span class="token keyword">SELECT</span> genre<span class="token punctuation">,</span> title<span class="token punctuation">,</span> publication_date <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> publication_date <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre <span class="token keyword">ASC</span><span class="token punctuation">,</span> publication_date <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price<span class="token punctuation">,</span> publication_date <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> <span class="token number">2</span> <span class="token keyword">DESC</span><span class="token punctuation">,</span> <span class="token number">3</span> <span class="token keyword">ASC</span><span class="token punctuation">;</span> <span class="token comment">-- Sort by price DESC, then by date ASC</span> |
⚠️ 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:
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- NULLs appear at the end in ASC order</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- NULLs appear at the beginning in DESC order</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span> <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">-- Force NULLs to appear first (regardless of ASC/DESC)</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">ASC</span> NULLS <span class="token keyword">FIRST</span><span class="token punctuation">;</span> <span class="token comment">-- Force NULLs to appear last</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span> NULLS <span class="token keyword">LAST</span><span class="token punctuation">;</span> |
This is incredibly useful when you want to see missing values prominently or hide them at the end.
3. Practical Example: Inventory Report
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token comment">-- Show books that need pricing (NULL prices first), then sort by price</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price<span class="token punctuation">,</span> in_stock <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price NULLS <span class="token keyword">FIRST</span><span class="token punctuation">,</span> price <span class="token keyword">ASC</span><span class="token punctuation">;</span> |
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
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort books by price after tax (adding 10% tax)</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price<span class="token punctuation">,</span> price <span class="token operator">*</span> <span class="token number">1.1</span> <span class="token keyword">AS</span> price_with_tax <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price_with_tax <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
2. Sorting by String Functions
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort books by the length of their title</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> LENGTH<span class="token punctuation">(</span>title<span class="token punctuation">)</span> <span class="token keyword">AS</span> title_length <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> title <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> title_length <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
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
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Sort titles case-insensitively</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> title <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> LOWER<span class="token punctuation">(</span>title<span class="token punctuation">)</span><span class="token punctuation">;</span> |
4. Complex Expressions
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="token comment">-- Sort books by "value" (rating × sold_copies)</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> rating<span class="token punctuation">,</span> sold_copies<span class="token punctuation">,</span> <span class="token punctuation">(</span>rating <span class="token operator">*</span> sold_copies<span class="token punctuation">)</span> <span class="token keyword">AS</span> popularity_score <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> rating <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> sold_copies <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> popularity_score <span class="token keyword">DESC</span> <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token keyword">SELECT</span> <span class="token keyword">DISTINCT</span> genre<span class="token punctuation">,</span> <span class="token keyword">CASE</span> genre <span class="token keyword">WHEN</span> <span class="token string">'Fiction'</span> <span class="token keyword">THEN</span> <span class="token number">1</span> <span class="token keyword">WHEN</span> <span class="token string">'Science Fiction'</span> <span class="token keyword">THEN</span> <span class="token number">2</span> <span class="token keyword">WHEN</span> <span class="token string">'Fantasy'</span> <span class="token keyword">THEN</span> <span class="token number">3</span> <span class="token keyword">WHEN</span> <span class="token string">'Thriller'</span> <span class="token keyword">THEN</span> <span class="token number">4</span> <span class="token keyword">ELSE</span> <span class="token number">5</span> <span class="token keyword">END</span> <span class="token keyword">AS</span> sort_order <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> sort_order<span class="token punctuation">,</span> genre<span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> in_stock<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> <span class="token keyword">CASE</span> <span class="token keyword">WHEN</span> in_stock <span class="token keyword">THEN</span> <span class="token number">0</span> <span class="token keyword">ELSE</span> <span class="token number">1</span> <span class="token keyword">END</span><span class="token punctuation">,</span> price<span class="token punctuation">;</span> |
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
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token comment">-- Sort by: 1. In stock first, 2. High rating first, 3. Low price first</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> in_stock<span class="token punctuation">,</span> rating<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> rating <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> <span class="token keyword">CASE</span> <span class="token keyword">WHEN</span> in_stock <span class="token keyword">THEN</span> <span class="token number">0</span> <span class="token keyword">ELSE</span> <span class="token number">1</span> <span class="token keyword">END</span><span class="token punctuation">,</span> rating <span class="token keyword">DESC</span><span class="token punctuation">,</span> price <span class="token keyword">ASC</span><span class="token punctuation">;</span> |
Part 8: Random Sorting
Sometimes you want random order – for features like “random book recommendation”:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token comment">-- Get 5 random books</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> author <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> in_stock <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> RANDOM<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">LIMIT</span> <span class="token number">5</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Get unique genres, sorted alphabetically</span> <span class="token keyword">SELECT</span> <span class="token keyword">DISTINCT</span> genre <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre<span class="token punctuation">;</span> |
Note: The columns in ORDER BY must appear in the SELECT list when using DISTINCT:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">-- This works - genre is in SELECT</span> <span class="token keyword">SELECT</span> <span class="token keyword">DISTINCT</span> genre <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre<span class="token punctuation">;</span> <span class="token comment">-- This might fail - price isn't in SELECT</span> <span class="token keyword">SELECT</span> <span class="token keyword">DISTINCT</span> genre <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price<span class="token punctuation">;</span> <span class="token comment">-- Error in some databases, but PostgreSQL allows it?</span> |
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
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">-- Find most common genres</span> <span class="token keyword">SELECT</span> genre<span class="token punctuation">,</span> <span class="token function">COUNT</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> book_count<span class="token punctuation">,</span> <span class="token function">AVG</span><span class="token punctuation">(</span>price<span class="token punctuation">)</span> <span class="token keyword">AS</span> avg_price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">GROUP</span> <span class="token keyword">BY</span> genre <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> book_count <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
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
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="token comment">-- Genres with highest average rating</span> <span class="token keyword">SELECT</span> genre<span class="token punctuation">,</span> <span class="token function">COUNT</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> book_count<span class="token punctuation">,</span> <span class="token function">ROUND</span><span class="token punctuation">(</span><span class="token function">AVG</span><span class="token punctuation">(</span>rating<span class="token punctuation">)</span>::<span class="token keyword">numeric</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> avg_rating <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> rating <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">GROUP</span> <span class="token keyword">BY</span> genre <span class="token keyword">HAVING</span> <span class="token function">COUNT</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">>=</span> <span class="token number">2</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> avg_rating <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
3. Multiple Aggregates
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token keyword">SELECT</span> genre<span class="token punctuation">,</span> <span class="token function">COUNT</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> count<span class="token punctuation">,</span> <span class="token function">SUM</span><span class="token punctuation">(</span>sold_copies<span class="token punctuation">)</span> <span class="token keyword">AS</span> total_sold<span class="token punctuation">,</span> <span class="token function">AVG</span><span class="token punctuation">(</span>price<span class="token punctuation">)</span> <span class="token keyword">AS</span> avg_price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">GROUP</span> <span class="token keyword">BY</span> genre <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> total_sold <span class="token keyword">DESC</span> NULLS <span class="token keyword">LAST</span><span class="token punctuation">,</span> avg_price <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
Part 11: Real-World Examples
Example 1: E-commerce Product Listing
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="token comment">-- Product listing with multiple sort options</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> author<span class="token punctuation">,</span> price<span class="token punctuation">,</span> rating<span class="token punctuation">,</span> in_stock <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> in_stock <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> <span class="token comment">-- First by stock status (though all are true here)</span> in_stock <span class="token keyword">DESC</span><span class="token punctuation">,</span> <span class="token comment">-- Then by featured status (could be another column)</span> <span class="token comment">-- Then by rating (high to low)</span> rating <span class="token keyword">DESC</span> NULLS <span class="token keyword">LAST</span><span class="token punctuation">,</span> <span class="token comment">-- Finally by price (low to high)</span> price <span class="token keyword">ASC</span><span class="token punctuation">;</span> |
Example 2: Bestseller List
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="token comment">-- Top 10 bestsellers by copies sold</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> author<span class="token punctuation">,</span> sold_copies<span class="token punctuation">,</span> RANK<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">OVER</span> <span class="token punctuation">(</span><span class="token keyword">ORDER</span> <span class="token keyword">BY</span> sold_copies <span class="token keyword">DESC</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> rank <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> sold_copies <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> sold_copies <span class="token keyword">DESC</span> <span class="token keyword">LIMIT</span> <span class="token number">10</span><span class="token punctuation">;</span> |
Example 3: Recently Published, Highly Rated Books
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="token comment">-- New releases with good ratings</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> author<span class="token punctuation">,</span> publication_date<span class="token punctuation">,</span> rating <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> publication_date <span class="token operator">></span> <span class="token string">'2015-01-01'</span> <span class="token operator">AND</span> rating <span class="token operator">></span> <span class="token number">4.5</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> publication_date <span class="token keyword">DESC</span><span class="token punctuation">,</span> rating <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
Example 4: Inventory Value Report
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">-- Calculate inventory value and sort by it</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price<span class="token punctuation">,</span> stock_quantity<span class="token punctuation">,</span> <span class="token punctuation">(</span>price <span class="token operator">*</span> stock_quantity<span class="token punctuation">)</span> <span class="token keyword">AS</span> inventory_value <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token operator">AND</span> stock_quantity <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> inventory_value <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
Example 5: Customer Orders Analysis
Let’s create an orders table for more examples:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> orders <span class="token punctuation">(</span> order_id <span class="token keyword">SERIAL</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span><span class="token punctuation">,</span> customer_name <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span> order_date <span class="token keyword">DATE</span><span class="token punctuation">,</span> total_amount <span class="token keyword">DECIMAL</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">status</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> orders <span class="token punctuation">(</span>customer_name<span class="token punctuation">,</span> order_date<span class="token punctuation">,</span> total_amount<span class="token punctuation">,</span> <span class="token keyword">status</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'Alice Johnson'</span><span class="token punctuation">,</span> <span class="token string">'2024-01-15'</span><span class="token punctuation">,</span> <span class="token number">125.50</span><span class="token punctuation">,</span> <span class="token string">'delivered'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Bob Smith'</span><span class="token punctuation">,</span> <span class="token string">'2024-01-20'</span><span class="token punctuation">,</span> <span class="token number">89.99</span><span class="token punctuation">,</span> <span class="token string">'delivered'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Alice Johnson'</span><span class="token punctuation">,</span> <span class="token string">'2024-02-01'</span><span class="token punctuation">,</span> <span class="token number">245.00</span><span class="token punctuation">,</span> <span class="token string">'shipped'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Carol White'</span><span class="token punctuation">,</span> <span class="token string">'2024-02-05'</span><span class="token punctuation">,</span> <span class="token number">56.75</span><span class="token punctuation">,</span> <span class="token string">'processing'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Bob Smith'</span><span class="token punctuation">,</span> <span class="token string">'2024-02-10'</span><span class="token punctuation">,</span> <span class="token number">112.30</span><span class="token punctuation">,</span> <span class="token string">'shipped'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'David Brown'</span><span class="token punctuation">,</span> <span class="token string">'2024-02-15'</span><span class="token punctuation">,</span> <span class="token number">78.25</span><span class="token punctuation">,</span> <span class="token string">'pending'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token string">'Alice Johnson'</span><span class="token punctuation">,</span> <span class="token string">'2024-02-20'</span><span class="token punctuation">,</span> <span class="token number">92.50</span><span class="token punctuation">,</span> <span class="token string">'pending'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">-- Customer purchase summary with sorting</span> <span class="token keyword">SELECT</span> customer_name<span class="token punctuation">,</span> <span class="token function">COUNT</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token keyword">AS</span> order_count<span class="token punctuation">,</span> <span class="token function">SUM</span><span class="token punctuation">(</span>total_amount<span class="token punctuation">)</span> <span class="token keyword">AS</span> total_spent<span class="token punctuation">,</span> <span class="token function">MAX</span><span class="token punctuation">(</span>order_date<span class="token punctuation">)</span> <span class="token keyword">AS</span> last_order <span class="token keyword">FROM</span> orders <span class="token keyword">GROUP</span> <span class="token keyword">BY</span> customer_name <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> total_spent <span class="token keyword">DESC</span><span class="token punctuation">,</span> order_count <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
Part 12: Performance Considerations
1. Indexes for Sorting
Indexes can dramatically speed up ORDER BY operations:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token comment">-- Index for single-column sorting</span> <span class="token keyword">CREATE</span> <span class="token keyword">INDEX</span> idx_books_price <span class="token keyword">ON</span> books<span class="token punctuation">(</span>price<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">-- Index for multi-column sorting (order matters!)</span> <span class="token keyword">CREATE</span> <span class="token keyword">INDEX</span> idx_books_genre_price <span class="token keyword">ON</span> books<span class="token punctuation">(</span>genre<span class="token punctuation">,</span> price <span class="token keyword">DESC</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">-- Index for expression sorting (less common)</span> <span class="token keyword">CREATE</span> <span class="token keyword">INDEX</span> idx_books_lower_title <span class="token keyword">ON</span> books<span class="token punctuation">(</span>LOWER<span class="token punctuation">(</span>title<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
2. When Indexes Help
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token comment">-- This can use index on price</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price<span class="token punctuation">;</span> <span class="token comment">-- This can use composite index (genre, price)</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> genre<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> genre <span class="token operator">=</span> <span class="token string">'Fiction'</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span><span class="token punctuation">;</span> <span class="token comment">-- This might not use index (different order)</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> genre<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span><span class="token punctuation">,</span> genre<span class="token punctuation">;</span> <span class="token comment">-- Index order is genre, price</span> |
3. LIMIT and Sorting
When combining ORDER BY with LIMIT, PostgreSQL can optimize by only sorting enough rows to satisfy the LIMIT:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<span class="token comment">-- PostgreSQL might use an index to find top 5 without full sort</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token keyword">FROM</span> books <span class="token keyword">WHERE</span> price <span class="token operator">IS</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token keyword">DESC</span> <span class="token keyword">LIMIT</span> <span class="token number">5</span><span class="token punctuation">;</span> |
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:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="token comment">-- Assuming a metadata JSONB column</span> <span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> products <span class="token punctuation">(</span> id <span class="token keyword">SERIAL</span><span class="token punctuation">,</span> name <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span> attributes JSONB <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">-- Sort by a JSON field</span> <span class="token keyword">SELECT</span> name<span class="token punctuation">,</span> attributes<span class="token operator">-</span><span class="token operator">>></span><span class="token string">'brand'</span> <span class="token keyword">AS</span> brand <span class="token keyword">FROM</span> products <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attributes<span class="token operator">-</span><span class="token operator">>></span><span class="token string">'brand'</span><span class="token punctuation">;</span> |
2. Natural Sort (Human-Friendly Sorting)
For strings with numbers, natural sorting often makes more sense:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="token comment">-- Create extension for natural sorting</span> <span class="token keyword">CREATE</span> EXTENSION <span class="token keyword">IF</span> <span class="token operator">NOT</span> <span class="token keyword">EXISTS</span> <span class="token string">"btree_gin"</span><span class="token punctuation">;</span> <span class="token comment">-- Or use regex to extract numbers for sorting</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> SUBSTRING<span class="token punctuation">(</span>title <span class="token keyword">FROM</span> <span class="token string">'^[^0-9]*'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">COALESCE</span><span class="token punctuation">(</span>SUBSTRING<span class="token punctuation">(</span>title <span class="token keyword">FROM</span> <span class="token string">'[0-9]+'</span><span class="token punctuation">)</span>::<span class="token keyword">INT</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
3. Collation-Specific Sorting
Different languages sort differently:
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token comment">-- Specify collation for sorting</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> title <span class="token keyword">COLLATE</span> <span class="token string">"en_US"</span><span class="token punctuation">;</span> |
Part 14: Common Mistakes and How to Avoid Them
Mistake 1: Forgetting ORDER BY Altogether
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- Results order is NOT guaranteed!</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books<span class="token punctuation">;</span> <span class="token comment">-- Always specify ORDER BY if order matters</span> <span class="token keyword">SELECT</span> title <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> title<span class="token punctuation">;</span> |
Mistake 2: Mixing ASC/DESC Incorrectly
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- This sorts by genre ASC, then price DESC</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre<span class="token punctuation">,</span> price <span class="token keyword">DESC</span><span class="token punctuation">;</span> <span class="token comment">-- This sorts by genre DESC, then price DESC</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> genre <span class="token keyword">DESC</span><span class="token punctuation">,</span> price <span class="token keyword">DESC</span><span class="token punctuation">;</span> |
Each column gets its own direction specification.
Mistake 3: Using Column Aliases Incorrectly
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token comment">-- This works in PostgreSQL</span> <span class="token keyword">SELECT</span> title<span class="token punctuation">,</span> price <span class="token operator">*</span> <span class="token number">1.1</span> <span class="token keyword">AS</span> price_with_tax <span class="token keyword">FROM</span> books <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price_with_tax<span class="token punctuation">;</span> <span class="token comment">-- But for maximum portability, use the expression</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price <span class="token operator">*</span> <span class="token number">1.1</span><span class="token punctuation">;</span> |
Mistake 4: Sorting by Large Text Columns
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token comment">-- Sorting by huge text columns can be slow</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> very_long_text_column<span class="token punctuation">;</span> <span class="token comment">-- Consider indexing or using a hash/summary</span> |
Mistake 5: Not Understanding NULL Behavior
|
0 1 2 3 4 5 6 7 8 9 10 |
<span class="token comment">-- NULLs might appear where you don't expect</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price<span class="token punctuation">;</span> <span class="token comment">-- NULLs at end in ASC</span> <span class="token comment">-- Control it explicitly</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> price NULLS <span class="token keyword">LAST</span><span class="token punctuation">;</span> |
Summary: The ORDER BY Philosophy
ORDER BY transforms raw data into meaningful information by revealing patterns, rankings, and relationships:
-
Basic sorting – Single column, ASC/DESC
-
Multi-level sorting – Primary, secondary, tertiary criteria
-
Expression sorting – Sort by calculated values
-
Conditional sorting – Custom logic with CASE
-
NULL handling – Control where missing values appear
-
Performance awareness – Indexes and query optimization
Remember the query execution order:
-
FROM (get tables)
-
WHERE (filter rows)
-
GROUP BY (group rows)
-
HAVING (filter groups)
-
SELECT (compute expressions)
-
ORDER BY (sort results) – HERE!
-
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?
