NULLS FIRST and NULLS LAST in SQL Sorting
Master how the ORDER BY clause arranges query results, controls multiple columns, applies limits, and manages missing information across database systems.
When you write a SELECT query without an ORDER BY clause, the database engine returns matching rows in whatever order it finds most efficient. That order is not guaranteed to match the insertion sequence, nor will it stay consistent if you update the underlying table. If your application, report, or user interface requires a predictable sequence, you must make that requirement explicit.
- 1. Row Order Without ORDER BY
- 2. Try This First: Comparing Default Output
- 3. Ascending and Descending Order
- 4. Multiple-Column Sorting
- 5. Deterministic Tie-Breaking
- 6. Combining ORDER BY with WHERE and LIMIT
- 7. Handling NULL Value Placement
- 8. Inspecting Execution Plans with EXPLAIN
- 9. My Practical Rules for ORDER BY
- 10. Homework Exercises
- 11. Knowledge Check Quiz
- 12. Frequently Asked Questions
- 13. Related Practice
Row Order Without ORDER BY
A common assumption among beginners is that database tables act like text files where rows stay neatly in the order they were typed in. Under the hood, relational databases store data in pages and blocks. When you request data using a basic SELECT statement without an explicit sort instruction, the storage engine fetches those rows based on disk layout, indexes, or temporary execution paths.
If your software needs data presented in alphabetical order, price order, or date order, rely on the ORDER BY clause rather than hoping the database will naturally present rows the way you expect.
Try This First: Comparing Default Output
Before diving into syntax rules, let's look at how a table behaves when you sort explicitly versus when you leave sorting up to the database engine. Suppose you have a sample products table containing items with varying prices.
Run the first query without any sorting clause:
SELECT product_name, price FROM products;
Now run the second query with an explicit sort instruction:
SELECT product_name, price FROM products ORDER BY price ASC;
Compare the two result sets. The first query returns rows in storage sequence, which can look completely random. The second query guarantees that rows are arranged from the lowest price to the highest price.
Ascending and Descending Order
The ORDER BY clause accepts one or more columns or expressions. By default, most database systems sort in ascending order if you omit the direction keyword. However, explicitly stating your intention makes your code much easier to read.
ASC: Arranges data from lowest to highest, oldest to newest, or alphabetically from A to Z.DESC: Arranges data from highest to lowest, newest to oldest, or alphabetically from Z to A.
SELECT product_name, price FROM products ORDER BY price DESC;
Multiple-Column Sorting
Real-world reporting often requires sorting by more than one attribute. For example, you might want to group items by category first, and then list the most expensive items at the top of each category.
SELECT product_name, category, price
FROM products
ORDER BY category ASC,
price DESC;
In this query, category is evaluated first. The database organizes all 'Accessories' together, all 'Laptops' together, and so on. Within each specific category, the price DESC rule takes over, placing higher-priced items above cheaper ones. Price is only used to break ties when category values are identical.
Deterministic Tie-Breaking
When multiple rows share the exact same value in your sort column, the database does not enforce a strict internal order for those tied rows unless you give it a secondary rule.
SELECT product_name, price
FROM products
ORDER BY price DESC,
id ASC;
Adding a unique column like a primary key (id ASC) as a final sort expression guarantees a stable, repeatable result every single time the query runs.
When two products have the identical price, sorting only by price leaves the relative position of those tied rows up to the storage engine's current execution plan. Adding id ASC as a secondary sort expression eliminates that randomness and ensures stable pagination in user interfaces.
Combining ORDER BY with WHERE and LIMIT
Sorting usually happens near the end of query execution, after rows have been filtered. When working with large datasets, combining clauses correctly keeps queries fast and reports accurate.
SELECT product_name, price FROM products WHERE category = 'Laptop' ORDER BY price DESC LIMIT 5;
The WHERE clause filters the table down to laptops only. Then, ORDER BY sorts those filtered laptops by price in descending order. Finally, LIMIT 5 restricts the output to the top five most expensive laptops. Keep in mind that LIMIT is standard MySQL and PostgreSQL syntax, though other database engines use different clauses like TOP or ROWNUM.
NULL Value Placement
Missing data introduces a sorting challenge: where should NULL values appear?
In MySQL, NULL values are treated as smaller than any other value. Therefore, in an ascending sort (ASC), NULL values appear at the very beginning of the result set. In a descending sort (DESC), they appear at the very end.
Other relational databases handle this differently. For example, PostgreSQL defaults to treating NULL values as larger than non-null values, meaning they appear at the end during an ascending sort. PostgreSQL also explicitly supports NULLS FIRST and NULLS LAST syntax to override this behavior.
-- PostgreSQL-only syntax example: SELECT product_name, price FROM products ORDER BY price ASC NULLS LAST;
If you need precise control over NULL placement in MySQL where NULLS FIRST or NULLS LAST is not natively supported in older versions, you can use a conditional expression in your ORDER BY clause, such as sorting by (price IS NULL) ASC first.
Inspecting Execution Plans with EXPLAIN
When dealing with large tables, sorting can become resource-intensive if the database engine cannot satisfy the requested order using an existing index. You can inspect how MySQL plans to execute your query by prepending the EXPLAIN keyword.
EXPLAIN SELECT product_name, price FROM products ORDER BY price DESC;
Depending on your table size, available indexes, and filters, MySQL may need an additional sorting phase. If the execution plan shows Using filesort, it simply indicates that MySQL is using an internal sorting algorithm to order the rows before returning them. A filesort is not automatically bad; it is standard behavior for queries that sort unindexed columns or large result sets.
My Practical Rules for ORDER BY
- If order matters, write ORDER BY: Never rely on default storage order for application logic or reports.
- Use a stable tie-breaker: Add a unique column like
id ASCwhen repeatable row ordering is critical. - Make intent explicit: Use
ASCorDESCso anyone reading your query understands the intended sort direction immediately. - Check EXPLAIN before indexing: Do not add an index solely because a query includes an
ORDER BYclause. Indexes consume storage and add overhead toINSERT,UPDATE, andDELETEoperations.
Homework Exercises
Test your understanding by trying these exercises against your practice database:
- Write a query that retrieves all products ordered by category alphabetically, and by price from highest to lowest within each category.
- Modify a query to return only the three cheapest products in the entire catalog.
- Add a secondary tie-breaker column to an existing sort query and observe how tied rows lock into a fixed sequence.
- Run an
EXPLAINstatement on a complex sorted query to inspect whether an index or a filesort operation is utilized.
Knowledge Check Quiz
Test your knowledge of SQL sorting principles with this 10-question quiz.
Frequently Asked Questions
Can I sort by a column that is not included in the SELECT list?
Yes. In standard SQL and MySQL, you can order your result set by any column present in the source tables, even if that column does not appear in your SELECT clause columns.
Does MySQL support NULLS FIRST and NULLS LAST syntax?
As of MySQL 8+, native NULLS FIRST or NULLS LAST syntax is not directly built into the ORDER BY clause. You can achieve custom null placement using conditional expressions or mathematical tricks.
Why does my sorted query run slowly on large tables?
If the database cannot utilize an existing index that matches your requested sort order, it may need to perform a filesort operation over a large number of filtered rows, increasing execution time.
Is LIMIT part of standard SQL?
LIMIT is widely supported in MySQL, PostgreSQL, and SQLite, but other database management systems like SQL Server use TOP, and Oracle uses FETCH FIRST clauses.
What is a deterministic sort?
A deterministic sort produces the exact same row order every single time it executes against identical data. Adding a unique primary key as a tie-breaker ensures determinism.
Related Practice
Continue strengthening your SQL querying skills with these practical exercises:
- Practice writing single-column and multi-column sort statements on sample tables.
- Experiment with
WHERE,ORDER BY, andLIMITcombined in a single query. - Analyze execution plans using
EXPLAINon tables with and without appropriate indexes. - Review foundational row selection concepts in the SELECT Statement Guide.
0 Comments