🧚 Listen! Beekeeper Studio is a fast, modern, and open source database GUI Download
January 8, 2026 By Matthew Rathbone

ORDER BY sorts the rows a query returns by one or more columns or expressions, ascending or descending. Without it, the database returns rows in whatever order is quickest. The examples work in PostgreSQL, MySQL, SQLite and SQL Server.

How to use ORDER BY

Put ORDER BY at the end of the query, after WHERE, GROUP BY and HAVING; only LIMIT comes after it. List the columns to sort by. Each one sorts in ascending order unless you add DESC:

SELECT columns
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC];
-- Input: customers
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 1           | Olivia Hart | 2024-03-12
-- 2           | Marcus Lee  | 2023-11-05
-- 3           | Zara Ahmed  | 2024-01-27
-- 4           | Ben Carter  | 2023-08-19

SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date;

-- Output:
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 4           | Ben Carter  | 2023-08-19
-- 2           | Marcus Lee  | 2023-11-05
-- 3           | Zara Ahmed  | 2024-01-27
-- 1           | Olivia Hart | 2024-03-12

SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date DESC;

-- Output:
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 1           | Olivia Hart | 2024-03-12
-- 3           | Zara Ahmed  | 2024-01-27
-- 2           | Marcus Lee  | 2023-11-05
-- 4           | Ben Carter  | 2023-08-19

Rules to know

  • DESC only applies to the column right before it. ORDER BY author, published DESC sorts authors A to Z, then each author’s books newest first:
-- Input: books
-- title               | author          | published
-- --------------------+-----------------+----------
-- Emma                | Jane Austen     | 1815
-- Bleak House         | Charles Dickens | 1853
-- Pride and Prejudice | Jane Austen     | 1813
-- Hard Times          | Charles Dickens | 1854

SELECT title, author, published
FROM books
ORDER BY author, published DESC;

-- Output:
-- title               | author          | published
-- --------------------+-----------------+----------
-- Hard Times          | Charles Dickens | 1854
-- Bleak House         | Charles Dickens | 1853
-- Emma                | Jane Austen     | 1815
-- Pride and Prejudice | Jane Austen     | 1813
  • Without ORDER BY, the order isn’t guaranteed. Rows often come back in the order they were inserted, until the table grows, an index changes or the query runs in parallel. That goes for LIMIT too: without ORDER BY it returns whichever rows the database reads first.
  • Tied rows come back in any order. Add a unique column, such as the ID, as the last sort column so the order is the same on every run:
-- Input: customers
-- customer_id | name       | signup_date
-- ------------+------------+------------
-- 3           | Mara Lind  | 2024-01-15
-- 1           | Owen Price | 2024-01-10
-- 4           | Tariq Aziz | 2024-01-15
-- 2           | Lily Shore | 2024-01-15

-- The three 2024-01-15 rows can come back in any order
SELECT * FROM customers ORDER BY signup_date;

-- Output:
-- customer_id | name       | signup_date
-- ------------+------------+------------
-- 1           | Owen Price | 2024-01-10
-- 3           | Mara Lind  | 2024-01-15
-- 4           | Tariq Aziz | 2024-01-15
-- 2           | Lily Shore | 2024-01-15

-- customer_id breaks the tie
SELECT * FROM customers ORDER BY signup_date, customer_id;

-- Output:
-- customer_id | name       | signup_date
-- ------------+------------+------------
-- 1           | Owen Price | 2024-01-10
-- 2           | Lily Shore | 2024-01-15
-- 3           | Mara Lind  | 2024-01-15
-- 4           | Tariq Aziz | 2024-01-15
  • NULLs sort first, except in PostgreSQL, which puts them last. That’s for ascending order; DESC flips it:
-- Input: users
-- name       | middle_name
-- -----------+------------
-- John Smith | Robert
-- Ana Lopez  | NULL
-- Kim Young  | Elise

SELECT name, middle_name
FROM users
ORDER BY middle_name;

-- Output:
-- name       | middle_name
-- -----------+------------
-- Ana Lopez  | NULL
-- Kim Young  | Elise
-- John Smith | Robert
-- (PostgreSQL puts Ana Lopez last instead)

To choose where NULLs go, see NULLS FIRST and NULLS LAST below.

Alternative syntax

You can sort by a column alias or by the column’s position in the SELECT list. An alias saves repeating an expression. A position is shorter but breaks silently when someone edits the SELECT list:

-- Input: employees
-- name     | monthly_salary
-- ---------+---------------
-- Ivy Chen | 5200
-- Max Dunn | 7600
-- Pia Roth | 4500

SELECT name, monthly_salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;  -- or ORDER BY 2 DESC

-- Output:
-- name     | annual_salary
-- ---------+--------------
-- Max Dunn | 91200
-- Ivy Chen | 62400
-- Pia Roth | 54000

NULLS FIRST and NULLS LAST after a sort column say where its NULLs go:

-- Input: the users table above

SELECT name, middle_name
FROM users
ORDER BY middle_name NULLS LAST;
-- MySQL and SQL Server don't support NULLS LAST. Sort on a CASE first instead:
-- ORDER BY CASE WHEN middle_name IS NULL THEN 1 ELSE 0 END, middle_name

-- Output:
-- name       | middle_name
-- -----------+------------
-- Kim Young  | Elise
-- John Smith | Robert
-- Ana Lopez  | NULL

MySQL has FIELD(), which sorts values in the order you list them. Elsewhere, use a CASE expression like the one in Sort tasks by priority below:

-- Input: products
-- product_name | category
-- -------------+------------
-- Cookbook     | Books
-- Raincoat     | Clothing
-- Tablet       | Electronics
-- Scarf        | Clothing

-- MySQL
SELECT * FROM products
ORDER BY FIELD(category, 'Electronics', 'Clothing', 'Books');

-- Output:
-- product_name | category
-- -------------+------------
-- Tablet       | Electronics
-- Raincoat     | Clothing
-- Scarf        | Clothing
-- Cookbook     | Books

When should you use ORDER BY?

Use ORDER BY whenever the order of the rows means something to whoever reads them. Most uses fall into one of these four.

Show a list in a predictable order

Names from A to Z, dates oldest first, IDs in sequence. Without ORDER BY the same query can return its rows in a different order from one run to the next, and pages of results can overlap or skip rows.

Find the highest or most recent values

Sort descending to put the biggest, newest or most expensive rows first, then add LIMIT to keep only the top few: best sellers, the latest orders, the highest scores.

Sort by more than one column

When the first sort column has ties, the next one decides the order within them: department then salary, grade then score, status then date. Each column can have its own direction.

Sort by a calculated value or a custom order

ORDER BY accepts any expression, not only columns: a total worked out from two columns, the length of a name, or a CASE expression that puts values like High, Medium and Low in an order the alphabet won’t give you.

Real examples of ORDER BY

Page through a customer list

ORDER BY with LIMIT and OFFSET returns one page at a time. Three customers signed up on the same day, so customer_id breaks the tie. Without it, the database could put the same customer on both pages and skip another:

-- Input: customers
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 1           | Nina Brandt | 2024-02-14
-- 2           | Theo Walsh  | 2023-09-30
-- 3           | Iris Novak  | 2024-02-14
-- 4           | Felix Moore | 2024-02-14
-- 5           | June Park   | 2024-03-22

-- Page 1
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 0;

-- Output:
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 2           | Theo Walsh  | 2023-09-30
-- 1           | Nina Brandt | 2024-02-14

-- Page 2
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 2;
-- SQL Server has no LIMIT: use OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY

-- Output:
-- customer_id | name        | signup_date
-- ------------+-------------+------------
-- 3           | Iris Novak  | 2024-02-14
-- 4           | Felix Moore | 2024-02-14

Show a leaderboard’s top three

Sort the scores from highest to lowest and keep the first three:

-- Input: players
-- username  | score
-- ----------+------
-- quokka42  | 1870
-- nightowl  | 2310
-- pixelpete | 1525
-- zara_k    | 2045
-- bytebard  | 1990

SELECT username, score
FROM players
ORDER BY score DESC
LIMIT 3;
-- SQL Server has no LIMIT: write SELECT TOP 3 username, score instead

-- Output:
-- username | score
-- ---------+------
-- nightowl | 2310
-- zara_k   | 2045
-- bytebard | 1990

Build an order report by status, value and date

Statuses sort alphabetically. Within each status the biggest orders come first, and orders of the same value show the newest first:

-- Input: orders
-- order_id | status     | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1001     | Shipped    | 120.00      | 2024-03-02
-- 1002     | Delivered  | 75.50       | 2024-02-20
-- 1003     | Shipped    | 120.00      | 2024-03-05
-- 1004     | Processing | 42.00       | 2024-03-06
-- 1005     | Delivered  | 210.00      | 2024-02-28

SELECT order_id, status, order_value, order_date
FROM orders
ORDER BY status ASC, order_value DESC, order_date DESC;

-- Output:
-- order_id | status     | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1005     | Delivered  | 210.00      | 2024-02-28
-- 1002     | Delivered  | 75.50       | 2024-02-20
-- 1004     | Processing | 42.00       | 2024-03-06
-- 1003     | Shipped    | 120.00      | 2024-03-05
-- 1001     | Shipped    | 120.00      | 2024-03-02

Sort tasks by priority

Alphabetical order would give High, Low, Medium. A CASE expression turns each priority into a number to sort by. Anything else, here a NULL, gets 4 and goes last, and the due date orders tasks within each priority:

-- Input: tasks
-- task_name      | priority | due_date
-- ---------------+----------+-----------
-- Update docs    | Low      | 2024-06-03
-- Fix login bug  | High     | 2024-06-10
-- Plan offsite   | NULL     | 2024-05-20
-- Renew SSL cert | High     | 2024-06-01
-- Review PR      | Medium   | 2024-06-04

SELECT task_name, priority, due_date
FROM tasks
ORDER BY
  CASE priority
    WHEN 'High' THEN 1
    WHEN 'Medium' THEN 2
    WHEN 'Low' THEN 3
    ELSE 4
  END,
  due_date;

-- Output:
-- task_name      | priority | due_date
-- ---------------+----------+-----------
-- Renew SSL cert | High     | 2024-06-01
-- Fix login bug  | High     | 2024-06-10
-- Review PR      | Medium   | 2024-06-04
-- Update docs    | Low      | 2024-06-03
-- Plan offsite   | NULL     | 2024-05-20

Further reading about ORDER BY

On this blog:

Official documentation:

Beekeeper Studio Is A Free & Open Source Database GUI

Best SQL query & editor tool I have ever used. It provides everything I need to manage my database. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio is fast, intuitive, and easy to use. Beekeeper supports loads of databases, and works great on Windows, Mac and Linux.

Beekeeper's Linux version is 100% full-featured, no cut corners, no feature compromises.

What Users Say About Beekeeper Studio

★★★★★
"Beekeeper Studio completely replaced my old SQL workflow. It's fast, intuitive, and makes database work enjoyable again."
— Alex K., Database Developer
★★★★★
"I've tried many database GUIs, but Beekeeper strikes the perfect balance between features and simplicity. It just works."
— Sarah M., Full Stack Engineer

Ready to Improve Your SQL Workflow?

download Download Free