JOIN three tables
Mastering SQL JOINs: Combining Data from Three Tables

Learn how to effectively join three or more tables in SQL to retrieve comprehensive datasets, covering essential concepts and practical examples for MySQL.
In relational databases, data is often distributed across multiple tables to maintain normalization and reduce redundancy. To retrieve a complete picture of related information, you frequently need to combine data from several tables. This article focuses on the fundamental technique of joining three tables using SQL, a common requirement in database queries. We'll explore the logic behind multi-table joins and provide practical examples using MySQL.
Understanding Multi-Table JOINs
Joining multiple tables extends the concept of a two-table join. Each subsequent JOIN clause connects a new table to the result set formed by the previous joins. The key is to identify the common columns (foreign keys) that link these tables together. For instance, if you have Customers, Orders, and Order_Items tables, you might join Customers to Orders on customer_id, and then join the result to Order_Items on order_id.
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--o{ ORDER_ITEM : contains
CUSTOMER {
INT customer_id PK
VARCHAR name
VARCHAR email
}
ORDER {
INT order_id PK
INT customer_id FK
DATE order_date
DECIMAL total_amount
}
ORDER_ITEM {
INT item_id PK
INT order_id FK
INT product_id
INT quantity
DECIMAL price
}Entity-Relationship Diagram for Customer, Order, and Order_Item tables
The most common type of join used for combining related data is the INNER JOIN. An INNER JOIN returns only the rows where there is a match in all joined tables. If a row in one table does not have a corresponding match in the other joined tables, it will not be included in the result set. Other join types like LEFT JOIN or RIGHT JOIN can be used when you need to include all rows from one table, even if there are no matches in the others.
Setting Up Sample Tables
Before we dive into the join queries, let's create some sample tables and populate them with data. This will allow us to demonstrate the JOIN operations effectively. We'll use three tables: authors, books, and genres.
CREATE TABLE authors (
author_id INT PRIMARY KEY AUTO_INCREMENT,
author_name VARCHAR(100) NOT NULL
);
CREATE TABLE genres (
genre_id INT PRIMARY KEY AUTO_INCREMENT,
genre_name VARCHAR(50) NOT NULL
);
CREATE TABLE books (
book_id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
author_id INT,
genre_id INT,
publication_year INT,
FOREIGN KEY (author_id) REFERENCES authors(author_id),
FOREIGN KEY (genre_id) REFERENCES genres(genre_id)
);
INSERT INTO authors (author_name) VALUES
('J.K. Rowling'),
('George Orwell'),
('Jane Austen');
INSERT INTO genres (genre_name) VALUES
('Fantasy'),
('Dystopian'),
('Classic'),
('Romance');
INSERT INTO books (title, author_id, genre_id, publication_year) VALUES
('Harry Potter and the Sorcerer''s Stone', 1, 1, 1997),
('1984', 2, 2, 1949),
('Pride and Prejudice', 3, 3, 1813),
('Animal Farm', 2, 2, 1945),
('Harry Potter and the Chamber of Secrets', 1, 1, 1998);
SQL statements to create and populate sample tables
Joining Three Tables with INNER JOIN
To retrieve information about books, their authors, and their genres, we need to join all three tables. We'll start by joining books with authors on author_id, and then join the result of that operation with genres on genre_id.
SELECT
b.title,
a.author_name,
g.genre_name,
b.publication_year
FROM
books b
INNER JOIN
authors a ON b.author_id = a.author_id
INNER JOIN
genres g ON b.genre_id = g.genre_id
ORDER BY
b.title;
SQL query to join three tables (books, authors, genres)
In this query:
FROM books b: We start with thebookstable and give it an aliasbfor brevity.INNER JOIN authors a ON b.author_id = a.author_id: This joinsbookswithauthorsusing theauthor_idcolumn, which is common to both tables. We aliasauthorsasa.INNER JOIN genres g ON b.genre_id = g.genre_id: This then joins the result of the previous join with thegenrestable, using thegenre_idcolumn. We aliasgenresasg.SELECT b.title, a.author_name, g.genre_name, b.publication_year: We select the desired columns from each of the joined tables.
b for books) when joining multiple tables. This makes your queries more readable and prevents ambiguity if column names are identical across different tables.Handling Missing Data with LEFT JOIN
What if you wanted to see all authors, even those who haven't written any books in our books table, along with their book and genre information if available? An INNER JOIN would exclude such authors. In this scenario, a LEFT JOIN is more appropriate. A LEFT JOIN returns all rows from the left table (the first table in the FROM clause or the table immediately preceding the LEFT JOIN clause) and the matching rows from the right table. If there's no match, NULL values will appear for the right table's columns.
INSERT INTO authors (author_name) VALUES ('New Author');
SELECT
a.author_name,
b.title,
g.genre_name
FROM
authors a
LEFT JOIN
books b ON a.author_id = b.author_id
LEFT JOIN
genres g ON b.genre_id = g.genre_id
ORDER BY
a.author_name, b.title;
SQL query using LEFT JOIN to include all authors
In this LEFT JOIN example, 'New Author' will appear in the result set, but their title and genre_name columns will show NULL because they have no corresponding entries in the books table. Notice how the order of joins matters with LEFT JOIN â the 'left' table dictates which rows are always included.
LEFT JOIN with multiple tables, be mindful of the order. Each LEFT JOIN preserves all rows from the table on its 'left' (the result of the previous join operation), even if there are no matches in the table on its 'right'.