SQL exercises with solutions: ORDER BY and LIMIT
Updated on
ORDER BY sorts (ASC ascending, DESC descending); LIMIT keeps the first n rows. These 6 exercises range from level 1 to level 2; they use the syntax of SQLite, SpeedQL’s SQL engine.
Tip: Add a second sort column to break ties.
Read the “ORDER BY, LIMIT” card in the cheat sheet
Exercise 1
Show the name and salary of every employee, from the lowest to the highest salary.
| id | name | department | salary |
|---|---|---|---|
| 1 | Alice | Finance | 32000 |
| 2 | Bob | IT | 41000 |
| 3 | Claire | Finance | 38000 |
| 4 | David | HR | 29000 |
| 5 | Emma | IT | 50000 |
| 6 | Farid | IT | 47000 |
| 7 | Gaelle | HR | 33000 |
| 8 | Hugo | Finance | 44000 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …, …
FROM …
ORDER BY … ASCShow the solution
SELECT name, salary
FROM employees
ORDER BY salary ASC;Expected result (8 rows, in this order):
| name | salary |
|---|---|
| David | 29000 |
| Alice | 32000 |
| Gaelle | 33000 |
| Claire | 38000 |
| Bob | 41000 |
| Hugo | 44000 |
| Farid | 47000 |
| Emma | 50000 |
Exercise 2
Show the name, department and salary of the employees, sorted by department (alphabetical order) and then, within each department, from the highest to the lowest salary.
| id | name | department | salary |
|---|---|---|---|
| 1 | Alice | Finance | 32000 |
| 2 | Bob | IT | 41000 |
| 3 | Claire | Finance | 38000 |
| 4 | David | HR | 29000 |
| 5 | Emma | IT | 50000 |
| 6 | Farid | IT | 47000 |
| 7 | Gaelle | HR | 33000 |
| 8 | Hugo | Finance | 44000 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …, …, …
FROM …
ORDER BY … ASC, … DESCShow the solution
SELECT name, department, salary
FROM employees
ORDER BY department ASC, salary DESC;Expected result (8 rows, in this order):
| name | department | salary |
|---|---|---|
| Hugo | Finance | 44000 |
| Claire | Finance | 38000 |
| Alice | Finance | 32000 |
| Gaelle | HR | 33000 |
| David | HR | 29000 |
| Emma | IT | 50000 |
| Farid | IT | 47000 |
| Bob | IT | 41000 |
Exercise 3
Show the name of the 3 cheapest products, from the cheapest to the most expensive.
| id | name | category | price | stock |
|---|---|---|---|---|
| 1 | Keyboard | Office | 25 | 40 |
| 2 | Mouse | Office | 15 | 0 |
| 3 | Screen | Display | 180 | 12 |
| 4 | Headset | Audio | 60 | 8 |
| 5 | Webcam | Office | 45 | 0 |
| 6 | Speaker | Audio | 35 | 25 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …
FROM …
ORDER BY … ASC
LIMIT …Show the solution
SELECT name
FROM products
ORDER BY price ASC
LIMIT 3;Expected result (3 rows, in this order):
| name |
|---|
| Mouse |
| Keyboard |
| Speaker |
Exercise 4
Show the name of the 2 highest-paid employees, highest salary first.
| id | name | department | salary |
|---|---|---|---|
| 1 | Alice | Finance | 32000 |
| 2 | Bob | IT | 41000 |
| 3 | Claire | Finance | 38000 |
| 4 | David | HR | 29000 |
| 5 | Emma | IT | 50000 |
| 6 | Farid | IT | 47000 |
| 7 | Gaelle | HR | 33000 |
| 8 | Hugo | Finance | 44000 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …
FROM …
ORDER BY … DESC
LIMIT …Show the solution
SELECT name
FROM employees
ORDER BY salary DESC
LIMIT 2;Expected result (2 rows, in this order):
| name |
|---|
| Emma |
| Farid |
Exercise 5
Show the name and number of goals of the 3 top scorers, from the most goals to the fewest.
| id | name | team_id | position | goals |
|---|---|---|---|---|
| 1 | Alex Moreau | 1 | FW | 9 |
| 2 | Bilal Sow | 1 | MF | 4 |
| 3 | Carl Weber | 2 | FW | 7 |
| 4 | Diego Ruiz | 2 | DF | 1 |
| 5 | Eli Novak | 3 | FW | 6 |
| 6 | Femi Adeyemi | 4 | FW | 11 |
| 7 | Goran Petrov | 4 | GK | 0 |
| 8 | Hugo Lamy | 5 | MF | 5 |
| 9 | Ivan Kral | 5 | DF | 2 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …, …
FROM …
ORDER BY … DESC
LIMIT …Show the solution
SELECT name, goals
FROM players
ORDER BY goals DESC
LIMIT 3;Expected result (3 rows, in this order):
| name | goals |
|---|---|
| Femi Adeyemi | 11 |
| Alex Moreau | 9 |
| Carl Weber | 7 |
Exercise 6
Show the city, day and maximum temperature of the 3 hottest readings, from the hottest down (on ties, by day then by city).
| id | city | day | temp_max | temp_min | rain_mm |
|---|---|---|---|---|---|
| 1 | Paris | 2025-07-01 | 24 | 15 | 0 |
| 2 | Paris | 2025-07-02 | 27 | 17 | 0 |
| 3 | Paris | 2025-07-03 | 22 | 16 | 4.5 |
| 4 | Paris | 2025-07-04 | 19 | 14 | 12 |
| 5 | Paris | 2025-07-05 | 23 | 13 | 0 |
| 6 | Lyon | 2025-07-01 | 26 | 16 | 0 |
| 7 | Lyon | 2025-07-02 | 29 | 18 | 0 |
| 8 | Lyon | 2025-07-03 | 31 | 19 | 0 |
| 9 | Lyon | 2025-07-04 | 24 | 17 | 8.5 |
| 10 | Lyon | 2025-07-05 | 22 | 15 | 3 |
| 11 | Marseille | 2025-07-01 | 30 | 21 | 0 |
| 12 | Marseille | 2025-07-02 | 32 | 22 | 0 |
| 13 | Marseille | 2025-07-03 | 33 | 23 | 0 |
| 14 | Marseille | 2025-07-04 | 29 | 21 | 0 |
| 15 | Marseille | 2025-07-05 | 28 | 20 | 0 |
Show the hint
Topics to use: ORDER BY, LIMIT.
Query structure:
SELECT …, …, …
FROM …
ORDER BY … DESC, …, …
LIMIT …Show the solution
SELECT city, day, temp_max
FROM readings
ORDER BY temp_max DESC, day, city
LIMIT 3;Expected result (3 rows, in this order):
| city | day | temp_max |
|---|---|---|
| Marseille | 2025-07-03 | 33 |
| Marseille | 2025-07-02 | 32 |
| Lyon | 2025-07-03 | 31 |
Practice with automatic checking
In SpeedQL, you write your query and it is checked straight away, on these tables and then on a hidden dataset.