Step 1 Understand it
Why you need it. "The 3 highest salaries", "the newest orders first", "page 2 of the results" — order matters to people. And without , the may return in any order it likes, which can change from one run to the next.
New words in this topic (tap one to see what it means)
Watch it happen
Read the animation as text
- Without ORDER BY, rows come back in no promised order. Here they happen to be in emp_id order.
- ORDER BY salary DESC: highest first. Ben and Chen tie on 70000, so their order is not decided yet — either could come first.
- The second sort column, name, breaks the tie: Ben before Chen. Now the order is fully decided.
- LIMIT 3 keeps the first three rows after sorting: Asha, Hana, Ben. Chen is cut off — even though he earns exactly what Ben earns. "Top 3" can hide a tie.
Picture it
flowchart LR A["rows in any order"] -->|"ORDER BY salary DESC, name"| B["1 Asha 95000<br/>2 Hana 80000<br/>3 Ben 70000<br/>4 Chen 70000<br/>5 Dara 60000 …"] B -->|"LIMIT 3"| C["Asha, Hana, Ben"]
The idea
ORDER BY salary sorts biggest first. Add more columns to break ties: ORDER BY salary DESC, name sorts by salary, and people with the same salary by name. ASC (smallest first) is the default. LIMIT 3 keeps the first 3 rows after sorting. OFFSET 3 skips 3 rows first, which is how page 2 works when there are 3 rows per page. Without an ORDER BY, LIMIT just takes whichever rows come first — an arbitrary choice.
The shape of it
SELECT columns
FROM table_name
ORDER BY column1 DESC, column2 ASC
LIMIT n OFFSET skip;Words in lower case are the parts you fill in.
How it works, step by step
- The database finds all the rows first (, then ).
- ORDER BY salary DESC puts the highest salary first: Asha 95000, Hana 80000, then Ben and Chen on 70000…
- Ben and Chen tie on salary, so the second sort column, name, decides: Ben before Chen.
- LIMIT 3 keeps the first three rows: Asha, Hana, Ben. Chen is cut off even though he earns the same as Ben.
- OFFSET 3 LIMIT 3 would skip those three and return the next three.
Analogy
A race. ORDER BY lines the runners up by finishing time; LIMIT 3 hands out gold, silver and bronze. OFFSET 3 LIMIT 3 is "who came 4th, 5th and 6th?".
Where the analogy breaks
In a race, two runners on the same time share a place. LIMIT doesn't: it cuts at exactly n rows, so if 3rd and 4th place tie, one of them is dropped without warning. Phase 5 () handles ties properly.
Worked examples
Sort by salary, then by name
SELECT name, salary
FROM employees
ORDER BY salary DESC, name;8 rows
| name | salary |
|---|---|
| Asha | 95000 |
| Hana | 80000 |
| Ben | 70000 |
| Chen | 70000 |
| Dara | 60000 |
| Fatima | 52000 |
| Eli | 45000 |
| Gus | 38000 |
DESC applies only to salary. name has no direction, so it is ASC (A to Z).
Top 3 with LIMIT — and the tie it hides
SELECT name, salary
FROM employees
ORDER BY salary DESC, name
LIMIT 3;3 rows
| name | salary |
|---|---|
| Asha | 95000 |
| Hana | 80000 |
| Ben | 70000 |
Chen earns the same as Ben but is cut off. If the question is "the top 3 salaries", say the tie out loud in an interview.
Page 2, three rows per page
SELECT order_id, order_date
FROM orders
ORDER BY order_date
LIMIT 3 OFFSET 3;3 rows
| order_id | order_date |
|---|---|
| 104 | 2024-01-21 |
| 105 | 2024-02-02 |
| 106 | 2024-02-12 |
OFFSET 3 skips the first page (orders 101–103). For page n, use OFFSET (n − 1) × page size.
Where do go?
SELECT name, city
FROM customers
ORDER BY city, name;6 rows
| name | city |
|---|---|
| Zoe | NULL |
| Omar | Bristol |
| Tom | Leeds |
| Tom | Leeds |
| Lena | London |
| Priya | London |
and put NULLs first when sorting A to Z; puts them last. Write NULLS FIRST or NULLS LAST to be sure.
Must-know points
- Without ORDER BY, row order is not guaranteed — even if it looks sorted today.
- ASC (default) is smallest first; DESC is largest first. Each column gets its own direction.
- Add a second sort column to break ties, so the order is the same every time.
- LIMIT cuts after sorting. It ignores ties.
- OFFSET skips rows; it is fine for small pages but slow for deep pages, because the skipped rows are still read.
Common mistakes
- Using LIMIT without ORDER BY and expecting the "top" rows.
- Writing
ORDER BY salary, name DESCand expecting both to be descending. DESC applies only to the column right before it. - Answering "top 3 salaries" with LIMIT 3 when there are ties.
In other databases
- uses
SELECT TOP 3 …, orOFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY. Oracle and the standard useFETCH FIRST 3 ROWS ONLY. PostgreSQL, MySQL and SQLite use LIMIT. - NULL position: PostgreSQL and Oracle put NULLs last for ASC; SQLite, MySQL and SQL Server put them first. PostgreSQL and SQLite accept NULLS FIRST / NULLS LAST.
Step 2 Go further (free, optional)
Optional. The notes above are written to be enough on their own. These free resources give a second explanation and more practice.
-
Read
W3Schools — SQL ORDER BY Keyword
short page with a try-it editor, free
-
Read
PostgreSQL docs — LIMIT and OFFSET
official documentation, free
-
Practice
SQLBolt — Lesson 4: Filtering and sorting Query results
interactive exercises in the browser, free
Step 3 Practise
Try each one yourself first: out loud, or written and run in the practice box below, which saves every query you run. Then open the answer and compare.
-
ExplainSay what it does and when to use it, in plain words, with no notes.
Explain why "the 3 highest-paid employees" with LIMIT 3 can be a wrong answer here.
Show answer
Because of a tie. Asha (95,000) and Hana (80,000) are first and second, and Ben and Chen both earn 70,000, so they share third place.
ORDER BY salary DESC LIMIT 3must cut one of them, and which one depends on the tie-breaker. With no tie-breaker it is whichever the database happens to return first. Either way you leave out someone who is just as highly paid.So first ask: should ties be included? If yes, the answer has 4 people. Use RANK or (Phase 5), or
WHERE salary >=the third-highest salary. If no, say how you break the tie, for exampleORDER BY salary DESC, name. -
Writefrom a blank page, then run it
Write a for the 2 most expensive products, showing product_name and price.
Show answer
Sort from most expensive and keep 2. The next product is the £25 desk lamp, so there is no tie to worry about here (but always check for one).
sqlSELECT product_name, price FROM products ORDER BY price DESC LIMIT 2;2 rows
product_name price Headphones 40 Backpack 30 -
Predictsay it before you run it
What does
SELECT name FROM employees ORDER BY hire_date DESC LIMIT 2;return?Show answer
Gus, then Hana: the two most recent hires. DESC puts the latest date first. Gus on 2023-04-03 and Hana on 2022-11-30. Dates in YYYY-MM-DD form sort correctly even though they are text.
sqlSELECT name, hire_date FROM employees ORDER BY hire_date DESC LIMIT 2;2 rows
name hire_date Gus 2023-04-03 Hana 2022-11-30 -
Edge casesSay what happens with NULLs, ties, duplicates or no rows at all, and fix it.
Write a query that lists customers by city, with the customer who has no city at the end, not the start.
Show answer
SQLite puts NULLs first when sorting A to Z, so Zoe would come first. Sort by "is the city missing?" first:
city IS NULLis 0 for a real city and 1 for NULL, so the missing one goes last.SQLite and PostgreSQL also accept
ORDER BY city NULLS LAST, name, which gives the same rows. TheIS NULLtrick also works in MySQL, which has no NULLS LAST.sqlSELECT name, city FROM customers ORDER BY city IS NULL, city, name;6 rows
name city Omar Bristol Tom Leeds Tom Leeds Lena London Priya London Zoe NULL
Practice box: write and run your answers here
Your queries in this box
Step 4 Interview-ready, then prove it
Your interview answer
About 20 to 40 seconds, said out loud.
ORDER BY sorts the final result, with ASC or DESC per column, and I always add a column so the order is deterministic. LIMIT and OFFSET then cut the sorted result. I point out two caveats: LIMIT ignores ties, so "top 3" may need RANK instead; and large OFFSETs are slow, so for deep I use keyset pagination — WHERE id greater than the last id seen.
Follow-up questions
Is the order of rows guaranteed without ORDER BY?
No. The database returns rows in whatever order is cheapest, and it can change with , data or version.
What is keyset pagination?
Instead of OFFSET, remember the last value you showed and ask for WHERE order_id > 106 ORDER BY order_id LIMIT 3. It uses the index, so page 1000 is as fast as page 1.
Can you ORDER BY a column you didn't ?
Yes, in most cases. The exception is with , where you can only sort by selected columns.
Tick each check when you can do it without notes
A topic is finished when you pass all four checks, not when you have read it. Be strict: if you had to look at the notes, it is not ticked yet.
- Explain Say what it does and when to use it, in plain words, with no notes.
- Write Write the query from a blank page, then run it to check.
- Predict Read a query and say which rows it returns before you run it.
- Edge cases Say what happens with NULLs, ties, duplicates or no rows at all, and fix it.
0 of 4 checks ticked.
Saved in this browser. Back it up or move it to another device.