The Ultimate Guide to Understanding SQL Joins
NicolasBrondinBernard
SQL joins allow you to combine data from multiple tables. Here is a simple guide for beginners, illustrated with diagrams and examples in MySQL.

Article published on 02/10/2025, last updated on 10/08/2026
What is a join?
In a database, information is often spread across several tables.
A join (JOIN) allows you to link these tables using a common column (often a primary key and a foreign key).
Example: a
userstable and anorderstable can be linked viausers.id = orders.user_id.
There are several types of joins, which allow us to link this data, giving it a particular meaning, filtering it, etc. Some joins are native to the DBMS (here MySQL for the examples), while others require some SQL logic to create!
The main joins
INNER JOIN
An inner join (INNER JOIN) only returns the rows from A that have a link with B.

SELECT *
FROM A
INNER JOIN B ON A.key = B.key;
| user.id | user.name | order.id | order.user_id | order.total |
|---|---|---|---|---|
| 1 | Alice | 101 | 1 | 49.99 |
| 2 | Bob | 102 | 2 | 89.00 |
Example: In an e-commerce software, we can use an INNER JOIN between users and orders to display only the customers who have placed an order.
LEFT JOIN
A left join (LEFT JOIN or LEFT OUTER JOIN) returns all rows from A, and the data from B when there is a match (otherwise NULL).
⚠️ Warning: If several rows of B are linked to a single row of A, then A will appear multiple times!

SELECT *
FROM A
LEFT JOIN B ON A.key = B.key;
| project.id | project.name | task.id | task.project_id | task.name |
|---|---|---|---|---|
| 1 | Site Web | 201 | 1 | Page d’accueil |
| 1 | Site Web | 202 | 1 | Contact |
| 1 | Site Web | 203 | 1 | Mentions légales |
| 2 | Application Mobile | NULL | NULL | NULL |
Example: in a project management software, a LEFT JOIN between projects and tasks allows you to display all projects, even those that don't yet have any assigned tasks.
RIGHT JOIN
A right join (RIGHT JOIN or RIGHT OUTER JOIN) returns all rows from B, and the data from A when there is a match (otherwise NULL).
ℹ️ Notes: In general, a right join is used to simplify the writing of a query instead of a left join, and for performance reasons in rare cases.

SELECT *
FROM A
RIGHT JOIN B ON A.key = B.key;
| user.id | user.name | booking.id | booking.user_id | booking.date |
|---|---|---|---|---|
| 1 | Alice | 301 | 1 | 2024-10-01 |
| NULL | NULL | 302 | NULL | 2024-10-03 |
Example: in a booking tool, a RIGHT JOIN between users and bookings allows you to display all bookings, even those linked to deleted accounts.
FULL JOIN
A full outer join (FULL JOIN or FULL OUTER JOIN) returns all rows from A and all rows from B, whether they match or not.

SELECT *
FROM A
LEFT JOIN B ON A.key = B.key
UNION
SELECT *
FROM A
RIGHT JOIN B ON A.key = B.key;
| student.id | student.name | exam.id | exam.student_id | exam.score |
|---|---|---|---|---|
| 1 | Alice | 701 | 1 | 15 |
| 2 | Bob | NULL | NULL | NULL |
| NULL | NULL | 702 | NULL | NULL |
Example: in a school management software, a FULL OUTER JOIN between students and exam_results would allow you to display all students (even those without a grade) and all exams (even those with no participants).
Special joins
Most use cases will be covered by the joins presented previously, but you may come across specific cases that require more complex joins.
LEFT ANTI JOIN
A left anti-join (LEFT ANTI JOIN) returns all rows from A, except when they have a link to B.

SELECT *
FROM A
LEFT JOIN B ON A.key = B.key
WHERE B.key IS NULL;
| user.id | user.name | order.id | order.user_id |
|---|---|---|---|
| 3 | Charlie | NULL | NULL |
| 4 | Diana | NULL | NULL |
Example: in a CRM, find customers who have never placed an order.
RIGHT ANTI JOIN
A right anti-join (RIGHT ANTI JOIN) returns all rows from B, except when they have a link to A.

SELECT *
FROM A
RIGHT JOIN B ON A.key = B.key
WHERE A.key IS NULL;
| employee.id | employee.name | payroll.id | payroll.user_id | payroll.amount |
|---|---|---|---|---|
| NULL | NULL | 501 | NULL | 3200 |
| NULL | NULL | 502 | NULL | 2800 |
Example: in an HR software, display employees registered in payroll but not yet present in the main HR database.
FULL ANTI JOIN
A full anti-join (FULL ANTI JOIN) returns all rows from A and B, except those that create a link between A and B.

SELECT *
FROM A
FULL OUTER JOIN B ON A.key = B.key
WHERE A.key IS NULL OR B.key IS NULL;
| person.id | person.name | animal.id | animal.owner_id | animal.name |
|---|---|---|---|---|
| 1 | Olivier | NULL | NULL | NULL |
| 2 | Karim | NULL | NULL | NULL |
| NULL | NULL | 23 | NULL | Milou |
| NULL | NULL | 25 | NULL | Bouli |
Example: on an animal shelter website, we want to find all the animals that no longer have owners, and all the owners who no longer have animals.
No spam. Only free content, news, and ever more resources to level up your skills!
Join +1500 developers
No comments yet