JOINs — Combining Tables
Pull related data from multiple tables together — like orders with their customer’s name.
What you will learn
- Understand why data is split across tables
- Join tables with INNER JOIN
- Use foreign keys
Related tables
Instead of repeating data, we split it across tables and link them. An orders table stores a user_id that points to the users table — a foreign key.
Picture these two small tables. Notice the orders table does not repeat the customer’s name — it just stores a user_id that matches an id in users:
| users.id | users.name |
|---|---|
| 1 | Asha |
| 2 | Ravi |
| orders.id | orders.user_id | orders.total |
|---|---|---|
| 101 | 1 | 500 |
| 102 | 2 | 250 |
| 103 | 1 | 900 |
To show each order with its customer’s name, we need data from both tables at once. A JOIN stitches them together by matching the user_id in orders to the id in users.
Note: We make the orders table for real in the Keys & Relationships lesson coming up, so do not worry if you cannot run the join just yet — focus on understanding the idea here. Once both tables exist with the sample rows above, this exact query will work.
INNER JOIN
A JOIN query has three parts. Read them in order, then look at the code:
- Choose the columns you want, naming the table for each so MySQL knows where to look:
orders.id, users.name, orders.total. - Start from one table:
FROM orders. - Attach the other table and say how they match:
INNER JOIN users ON orders.user_id = users.id.
SELECT orders.id, users.name, orders.total
FROM orders
INNER JOIN users ON orders.user_id = users.id;For every order, MySQL looks at its user_id, finds the row in users with the matching id, and glues the two rows side by side — so you can pull users.name right next to the order’s details. The table.column naming (like orders.total) avoids confusion when both tables have a column with the same name (both have id).
Note: Output:
orders.id users.name orders.total
101 Asha 500
102 Ravi 250
103 Asha 900
Each order now shows the customer’s name instead of a bare user_id. Orders 101 and 103 both belong to user 1, so both show “Asha”. The join looked up the name from the users table for us.
Note: The ON clause says how the tables connect (orders.user_id = users.id). An INNER JOIN returns rows that match in both tables. There are also LEFT/RIGHT joins for including unmatched rows.
Tip: This is the superpower of relational databases — no duplicated data, everything linked. Laravel’s Eloquent makes joins feel effortless with “relationships”, which you will meet next.
Q. What does the ON clause in a JOIN specify?
✍️ Practice
- Create
usersandorderstables linked byuser_id. - Join them to list each order with the customer’s name.
🏠 Homework
- Model books and authors in two tables and join them.