A SELF JOIN joins a table to itself. It is ideal for modelling hierarchical or comparative relationships stored in a single table—such as employees and their managers, products and sub-categories, or pairwise comparisons.
SELECT
a.column_name,
b.related_column
FROM table_name a
JOIN table_name b
ON a.common_field = b.related_field;
Alias names (a and b) create two logical copies of the same table so that you can compare rows to each other.
| emp_id | emp_name | manager_id |
|---|---|---|
| 1 | John | NULL |
| 2 | Emma | 1 |
| 3 | Alex | 1 |
| 4 | Sarah | 2 |
SELECT
e.emp_name AS employee,
m.emp_name AS manager
FROM employees e
LEFT JOIN employees m
ON e.manager_id = m.emp_id;
The LEFT JOIN keeps top-level employees (with NULL managers) in the output.
SELECT
e1.emp_name AS employee,
e2.emp_name AS lower_paid_employee
FROM employees e1
JOIN employees e2
ON e1.salary > e2.salary;
SELECT
s1.id,
s1.name,
s1.email
FROM students s1
JOIN students s2
ON s1.email = s2.email
AND s1.id <> s2.id;
This pattern detects duplicated values by matching rows with the same email but different IDs.
SELECT
c1.category_name AS parent_category,
c2.category_name AS sub_category
FROM categories c1
JOIN categories c2
ON c1.category_id = c2.parent_id;
Great for traversing product hierarchies or building breadcrumb navigation.
LEFT JOIN when you must keep unmatched parent rows.a.id <> b.id).