SQL Multi-Table JOINs Practice Exercises
Learn to join two or more tables and practice with free exercises
What is a JOIN?
A JOIN combines rows from two or more tables based on a related column between them — usually an ID that appears in both. Real-world data is normally split across separate tables like this, so joins are how you bring related information back together in one result.
-- Combine order data with the customer who placed each order SELECT o.order_id, c.customer_name, c.city, o.book_title, o.price_usd FROM bookstore_orders o JOIN bookstore_customers c ON o.customer_id = c.customer_id;
The ON clause tells SQL how the two tables relate — here, bookstore_orders.customer_id matches bookstore_customers.customer_id. Plain JOIN (also written INNER JOIN) only returns rows where a match exists in both tables.
LEFT JOIN — keeping unmatched rows
LEFT JOIN keeps every row from the left (first) table, whether or not it has a match in the right table. When there's no match, the right table's columns come back as NULL instead of the row being dropped.
-- Every customer, including those who have never placed an order SELECT c.customer_name, o.book_title, o.order_date FROM bookstore_customers c LEFT JOIN bookstore_orders o ON c.customer_id = o.customer_id;
Any customer with no matching row in bookstore_orders still appears once, with book_title and order_date shown as NULL.
💡 JOIN types at a glance
| Join type | Returns |
|---|---|
INNER JOIN | Only rows with a match in both tables |
LEFT JOIN | All rows from the left table, matched or not |
RIGHT JOIN | All rows from the right table, matched or not |
FULL JOIN | All rows from both tables, matched or not |
Joining three or more tables
You can chain as many JOIN clauses as needed. Each one links a new table using its own ON condition, and the result flows through — a table joined later can still be connected back to any table joined earlier.
-- Combine rental, customer, and car details in one result SELECT r.rental_id, cu.customer_name, ca.car_model, r.rental_date FROM car_rentals r JOIN rental_customers cu ON r.customer_id = cu.customer_id JOIN rental_cars ca ON r.car_id = ca.car_id;
Here, car_rentals is the hub table connecting to both rental_customers and rental_cars — each joined on its own foreign key.
Common mistakes
Forgetting the ON clause — a JOIN without a matching condition produces a cartesian product, pairing every row in one table with every row in the other. Always pair a JOIN with an ON.
Ambiguous column names — when two joined tables share a column name (like customer_id), you must prefix it with a table alias, or SQL won't know which one you mean.
Using INNER JOIN when you need LEFT JOIN — an INNER JOIN silently drops rows with no match. If you need to see every customer even without orders, that's a LEFT JOIN, not an INNER JOIN.
Losing track of which table a column belongs to — once you're joining three or more tables, always alias each table and prefix every column, even ones that aren't ambiguous yet — it keeps the query readable as it grows.
SQL Multi-Table JOINs Exercises
Apply what you learned above. Write a query that matches each task.
Table Schemas
Task
Tip: Ctrl + Enter to submit