The ORDER BY clause in SQL acts like a personal organizer for your database results. It takes messy, unordered data and arranges it exactly how you want. Without ORDER BY, your query results come back in whatever random order the database feels like giving them – about as organized as a teenager’s bedroom.
Here’s the basic syntax:
SELECT column1, column2
FROM table_name
ORDER BY column1 ASC|DESC;
The ORDER BY clause always comes last in a SELECT statement, after any WHERE, GROUP BY, and HAVING clauses. If you’re just starting with SQL, our SQL beginner’s guide covers these fundamentals in more detail.
Basic Sorting with ASC and DESC
ASCending Order (Default)
When you want results from A to Z or 1 to 100:
SELECT product_name, price
FROM products
ORDER BY price ASC;
The ASC keyword is optional since it’s the default. This query shows products from cheapest to most expensive.
DESCending Order
For Z to A or 100 to 1 sorting:
SELECT employee_name, hire_date
FROM employees
ORDER BY hire_date DESC;
This displays employees with the most recent hires first – perfect for HR reports.
Pro Tip: Always specify ASC or DESC even though ASC is default. It makes your code more readable and prevents confusion.
Sorting by Multiple Columns
Real-world sorting often needs multiple levels, like sorting names by last name then first name:
SELECT first_name, last_name, department
FROM employees
ORDER BY department ASC, last_name ASC, first_name ASC;
This sorts employees by:
- Department (A-Z)
- Last name (A-Z within each department)
- First name (A-Z when last names match)
For more complex query building, check out our guide to ActiveRecord queries in Rails.
Handling NULL Values in Sorting
NULL values can behave unexpectedly in sorts. By default:
- In ASC order, NULLs appear first
- In DESC order, NULLs appear last
To control NULL placement explicitly:
-- NULLs last in ascending sort
SELECT product_name, weight
FROM products
ORDER BY weight ASC NULLS LAST;
-- NULLs first in descending sort
SELECT customer_name, discount_rate
FROM customers
ORDER BY discount_rate DESC NULLS FIRST;
Sorting with Expressions and Functions
You can sort by calculated values:
-- Sort by name length
SELECT username
FROM users
ORDER BY LENGTH(username) DESC;
-- Sort by discounted price
SELECT product_name, price, discount
FROM products
ORDER BY (price * (1 - discount)) ASC;
For developers working with Ruby on Rails, we’ve covered similar sorting concepts in our Rails scopes article.
Combining ORDER BY with Other Clauses
With WHERE
Filter first, then sort:
SELECT product_name, stock_quantity
FROM inventory
WHERE warehouse_id = 5
ORDER BY stock_quantity DESC;
With JOIN
Sort joined data:
SELECT c.customer_name, o.order_date, o.total_amount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY c.customer_name, o.order_date DESC;
With GROUP BY
Sort aggregated results:
SELECT department, COUNT(*) as employee_count
FROM employees
GROUP BY department
ORDER BY employee_count DESC;
Performance Considerations
Sorting large datasets can be expensive. Here’s how to optimize:
- Limit results when possible:
SELECT * FROM logs ORDER BY timestamp DESC LIMIT 100;
- Use indexes on frequently sorted columns
- Avoid sorting on calculated fields when possible
For database performance tips, see our PostgreSQL indexing guide.
Common Mistakes to Avoid
- Assuming default order: Without ORDER BY, order isn’t guaranteed
- Overcomplicating sorts: Start simple, then add complexity
- Mixing ASC/DESC unintentionally: Be explicit with each column
- Sorting unnecessary data: Filter first with WHERE
- Ignoring NULL behavior: Test how NULLs sort in your database
For more on writing clean queries, see our clean code practices.
Real-World Examples
E-Commerce Product Listing
SELECT product_name, price, rating, review_count
FROM products
WHERE category = 'Electronics'
AND stock_quantity > 0
ORDER BY
CASE WHEN sale_end_date > NOW() THEN 0 ELSE 1 END, -- Sale items first
rating DESC,
review_count DESC,
price ASC;
Employee Directory
SELECT
last_name,
first_name,
department,
hire_date
FROM employees
WHERE active = true
ORDER BY
department ASC,
last_name ASC,
first_name ASC;
Sales Reporting
SELECT
salesperson_id,
SUM(amount) as total_sales,
COUNT(*) as transaction_count
FROM sales
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY salesperson_id
ORDER BY total_sales DESC
LIMIT 10;
Advanced Sorting Techniques
Conditional Sorting with CASE
SELECT product_name, stock_quantity
FROM inventory
ORDER BY
CASE
WHEN stock_quantity = 0 THEN 1
WHEN stock_quantity < 10 THEN 2
ELSE 3
END,
product_name;
Custom Sort Orders
SELECT status, order_id, customer_name
FROM orders
ORDER BY
CASE status
WHEN 'Processing' THEN 1
WHEN 'Shipped' THEN 2
WHEN 'Delivered' THEN 3
ELSE 4
END,
order_date DESC;
Best Practices
- Be explicit: Always specify ASC/DESC for each column
- Put the most important sort first: Secondary sorts only break ties
- Test with real data: Small datasets may sort differently than production
- Consider pagination: Use LIMIT and OFFSET with sorted queries
- Document complex sorts: Comments help maintain tricky sorting logic
For more database best practices, explore our SQL performance guide.
Testing Your Knowledge
After reading this guide, test your SQL skills with our interactive SQL quiz to reinforce these sorting concepts.
Conclusion
The ORDER BY clause transforms chaotic query results into meaningful, organized data. Whether you’re sorting simple lists or creating complex multi-level sorts, understanding these techniques will make your applications more useful and your reports more professional.
Remember that proper sorting:
- Makes data easier to understand
- Improves user experience in applications
- Helps highlight important information
- Works hand-in-hand with filtering and grouping
Start with basic single-column sorts, then gradually incorporate more advanced techniques as your needs grow. With practice, you’ll be sorting data like a database pro.