Joins with WHERE and ORDER BY
A join combines with everything you know: WHERE, ORDER BY, LIMIT and functions. WHERE and ORDER BY come after the joins, and they can use the columns of all the joined tables. Which games were in refunded orders?
SELECT o.id, o.ordered_at, g.title
FROM order_items AS i
JOIN orders AS o ON i.order_id = o.id
JOIN games AS g ON i.game_id = g.id
WHERE o.status = 'refunded'
ORDER BY o.ordered_at, g.title;| id | ordered_at | title |
|---|---|---|
| 7 | 2024-06-01 | Shadow Ninja |
| 18 | 2025-03-28 | Galaxy Trader |
Remember from the previous lesson the order in which the parts of a query run. First comes FROM, now with all its JOINs: they build the joined rows. Then WHERE keeps some of them, and after it come GROUP BY, HAVING, SELECT, ORDER BY and LIMIT. So WHERE and ORDER BY see the columns of every joined table, whether you show them or not. The query above filters by o.status and sorts by o.ordered_at, and it would work even if neither of them were in SELECT.
A join also lets you compare the columns of two tables with each other, which no query on one table can do. Which items were sold for less than the game's price in the catalog?
SELECT i.order_id, g.title, g.price AS list_price, i.price AS paid
FROM order_items AS i
JOIN games AS g ON i.game_id = g.id
WHERE i.price < g.price
ORDER BY i.order_id, g.title;| order_id | title | list_price | paid |
|---|---|---|---|
| 28 | Shadow Ninja | 25 | 15 |
| 28 | Zombie Town | 30 | 20 |
Just the two games of the Black Friday order. In WHERE, qualified names matter as much as in SELECT: WHERE price > 20 would end with the error ambiguous column name: price.
Typical mistake: WHERE before a JOIN. The order of the parts is fixed: all the JOINs belong to FROM, and WHERE comes after the last of them. Otherwise, you get the error near "JOIN": syntax error.
Instructions
Which games did the customers from Leeds buy? Show the customer's name, the date of the order (ordered_at) and the title of the game, only for the customers whose city is Leeds. Sort the rows by ordered_at, then by title:
| name | ordered_at | title |
|---|---|---|
| Noah Wilson | 2024-04-02 | Castle Siege |
| Noah Wilson | 2024-04-02 | Galaxy Trader |
| Noah Wilson | 2024-12-23 | Tiny Kingdoms |
| Isla Young | 2025-11-20 | Knight's Oath |
| Noah Wilson | 2025-12-22 | Bakery Story |
| Noah Wilson | 2025-12-22 | Moon Farm |
Below it, find the orders that customers placed less than two weeks after they joined the shop: show the customer's name, the day they joined (joined) and the date of the order (ordered_at), for the orders where the difference between the two dates is less than 14 days. Use julianday() from lesson 4. Sort the rows by ordered_at:
| name | joined | ordered_at |
|---|---|---|
| Oscar King | 2024-11-30 | 2024-12-05 |
| Grace Hall | 2025-02-12 | 2025-02-14 |
| Sophie Adams | 2025-08-21 | 2025-08-30 |
Start programming for free
5/12