π MySQL Joins β Complete Guide with Practical Examples
In MySQL, JOIN clauses allow you to combine rows from two or more tables based on related columns.
Weβll use these three sample tables:
π¨βπΌ employees Table
| employee_id | name | department_id | manager_id |
|---|---|---|---|
| 1 | Alice | 1 | NULL |
| 2 | Bob | 2 | 1 |
| 3 | Charlie | 3 | 1 |
| 4 | David | NULL | 2 |
| 5 | Eva | 2 | 2 |
π’ departments Table
| department_id | department_name |
|---|---|
| 1 | HR |
| 2 | IT |
| 4 | Marketing |
π» laptops Table
| laptop_id | employee_id | brand |
|---|---|---|
| 1 | 1 | Dell |
| 2 | 2 | HP |
| 3 | 3 | Lenovo |
| 4 | 5 | Apple |
β 1οΈβ£ INNER JOIN β Only Matching Rows
Goal: Get employee names with their department names.
β Result: Only employees with matching departments.
| name | department_name |
|---|---|
| Alice | HR |
| Bob | IT |
| Eva | IT |
π₯ Charlie (dept 3 not in departments) and David (no department) are excluded.

β 2οΈβ£ LEFT JOIN β All from Left + Matching from Right
Goal: List all employees, even if no department exists.
β Result:
| name | department_name |
|---|---|
| Alice | HR |
| Bob | IT |
| Charlie | NULL |
| David | NULL |
| Eva | IT |
All employees included. Charlie and David have no matching departments.

β 3οΈβ£ RIGHT JOIN β All from Right + Matching from Left
Goal: List all departments, even if no employees exist.
β Result:
| name | department_name |
|---|---|
| Alice | HR |
| Bob | IT |
| Eva | IT |
| NULL | Marketing |
π₯ Marketing has no employees, so name is NULL.

β 4οΈβ£ CROSS JOIN β All Combinations
Goal: Show all possible employee-department combinations.
β Result: 5 employees Γ 3 departments = 15 rows.
| name | department_name |
|---|---|
| Alice | HR |
| Alice | IT |
| Alice | Marketing |
| Bob | HR |
| … | … |
Used rarely, but helpful for creating combinations or matrices.

β 5οΈβ£ SELF JOIN β Relating a Table to Itself
Goal: Show which employee reports to whom (using manager_id).
β Result:
| Employee | Manager |
|---|---|
| Alice | NULL |
| Bob | Alice |
| Charlie | Alice |
| David | Bob |
| Eva | Bob |
β 6οΈβ£ JOIN with a Third Table (Laptop Info)
Goal: Show each employee with their laptop brand and department.
β Result:
| name | department_name | brand |
|---|---|---|
| Alice | HR | Dell |
| Bob | IT | HP |
| Charlie | NULL | Lenovo |
| David | NULL | NULL |
| Eva | IT | Apple |
π All employees shown β laptop and department shown if exists.
β 7οΈβ£ FULL OUTER JOIN (Simulated in MySQL)
MySQL doesnβt support FULL OUTER JOIN natively. You can simulate it using UNION.
Goal: Get all employees and all departments even if no match.
— RIGHT JOIN part
SELECT e.name, d.department_name
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.department_id;
β Combines unmatched records from both sides.
β 8οΈβ£ UNION β Merge Query Results Vertically
Goal: Combine all employee names and department names into one list.
β Result: One-column result with all unique names (no duplicates).
π Summary Table
| JOIN Type | Description | NULLs When No Match? |
|---|---|---|
INNER JOIN |
Only matching rows from both tables | β |
LEFT JOIN |
All from left + matches from right | β Right side |
RIGHT JOIN |
All from right + matches from left | β Left side |
CROSS JOIN |
All combinations (Cartesian product) | β |
SELF JOIN |
Join a table to itself | β |
UNION |
Merge results vertically (distinct only) | β Duplicates removed |
UNION ALL |
Same as UNION, but includes duplicates | β |
FULL OUTER JOIN |
Simulated using UNION of LEFT + RIGHT JOIN | β Both sides |
