LearnContact
Lesson 5119 min read

SELF JOIN

Learn how to join a table to itself using aliases, and use it to model hierarchical relationships like employees and managers.

Introduction

Every join so far has connected two different tables. But what happens when the relationship you need actually lives inside a single table — like an employee whose manager is also an employee, in that very same table? That is exactly the problem a SELF JOIN solves.

This lesson explains what a self join is, why it requires table aliases, and walks through a full worked example connecting employees to their managers.

What You Will Learn
  • What a self join is and when it is needed.
  • Why hierarchical data (like manager relationships) needs a self join.
  • Why aliases are required to distinguish the two "copies" of the table.
  • A full worked example listing each employee with their manager's name.

What is a SELF JOIN?

A self join is simply a regular join (usually INNER JOIN or LEFT JOIN) where a table is joined to itself. MySQL does not have a separate SELF JOIN keyword — you just reference the same table twice in the same query, giving each reference its own alias so MySQL (and you) can tell them apart.

Self joins are most common with hierarchical or comparative data: employees and managers, categories and subcategories, or comparing rows within the same table (like finding pairs of products with the same price).

Simple Definition
  • A self join connects a table to itself, using two different aliases.
  • It is used when a row references another row in the same table.
  • There is no special SELF JOIN keyword — it uses ordinary INNER JOIN or LEFT JOIN syntax.

The Sample Table

Consider an "employees" table where each row has a manager_id column, pointing to the id of another employee in that same table.

setup.sql
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    manager_id INT
);

INSERT INTO employees VALUES
    (1, 'Rita', NULL),
    (2, 'Alex', 1),
    (3, 'Sam', 1),
    (4, 'Priya', 2),
    (5, 'Owen', 2);

Rita (id 1) has manager_id NULL, meaning she has no manager — perhaps she is the CEO. Alex and Sam both report to Rita. Priya and Owen both report to Alex.

Why Aliases Are Required

If we tried to write "FROM employees JOIN employees" without aliases, MySQL would not be able to tell the two references to the employees table apart, and the query would fail. Aliases solve this by giving each reference to the table a distinct, temporary name for the duration of the query.

A common convention is to alias one copy as "e" (the employee) and the other as "m" (the manager), which also makes the query easier to read.

Basic Syntax

SELECT e.column, m.column
FROM employees AS e
JOIN employees AS m
    ON e.manager_id = m.id;

Here, "e" represents each employee row, and "m" represents the row for that employee's manager — both coming from the exact same underlying table.

Worked Example

Let's list every employee alongside the name of their manager, by joining employees to itself on manager_id = id.

self_join.sql
SELECT e.name AS employee_name, m.name AS manager_name
FROM employees AS e
LEFT JOIN employees AS m
    ON e.manager_id = m.id;
Result
+---------------+---------------+
| employee_name | manager_name  |
+---------------+---------------+
| Rita          | NULL          |
| Alex          | Rita          |
| Sam           | Rita          |
| Priya         | Alex          |
| Owen          | Alex          |
+---------------+---------------+

We deliberately used LEFT JOIN instead of INNER JOIN here. Rita has no manager (manager_id is NULL), so an INNER JOIN would have excluded her entirely from the results. LEFT JOIN keeps every employee, showing NULL for manager_name when there is no manager to match.

Note

The AS keyword after each column alias (employee_name, manager_name) is what makes the output columns readable — without it, both name columns would confusingly both be labeled "name."

Finding Employees With No Manager

Combining what we learned about LEFT JOIN in an earlier lesson with a self join, we can specifically find employees who have no manager at all.

no_manager.sql
SELECT e.name
FROM employees AS e
LEFT JOIN employees AS m
    ON e.manager_id = m.id
WHERE m.id IS NULL;
Result
+------+
| name |
+------+
| Rita |
+------+

This is the same LEFT JOIN + IS NULL pattern from an earlier lesson, just applied to a table joined with itself.

Other Uses of SELF JOIN

Manager/employee hierarchies are the classic example, but self joins solve several other common problems too.

Category Trees

A "categories" table where each category has a parent_category_id pointing to another row in the same table.

Comparing Rows

Finding pairs of products in the same table that share the same price or category.

Location Hierarchies

Cities referencing their parent region, which itself is a row in the same table.

Peer Relationships

A "friends" or "follows" table connecting one user's id to another user's id in the same users table.

Common Mistakes

Avoid These Mistakes
  • Forgetting aliases entirely, which MySQL will reject since it cannot tell the two references to the table apart.
  • Mixing up which alias represents the employee and which represents the manager in the ON clause.
  • Using INNER JOIN when some rows (like a top-level manager with no manager of their own) have no match — LEFT JOIN is usually the safer default for hierarchies.
  • Forgetting to alias the output columns, resulting in two columns confusingly both named "name."

Best Practices

  • Always alias both references of the table clearly, like "e" for the employee side and "m" for the manager side.
  • Alias the output columns too (employee_name, manager_name) so results are unambiguous.
  • Default to LEFT JOIN for hierarchical self joins, since a top-level row often has no parent.
  • Draw the relationship out on paper first for deeper hierarchies (more than two levels) before writing the query.

Frequently Asked Questions

Is there a special SELF JOIN keyword in MySQL?

No. You use ordinary INNER JOIN or LEFT JOIN syntax, just referencing the same table twice with two different aliases.

Why do I need two aliases for one table?

Without aliases, MySQL cannot distinguish which reference to the table a column belongs to, since both copies share the exact same table and column names.

Can a self join go more than one level deep, like grandmanager?

Yes, by joining the same table a third time with yet another alias, though this gets complex quickly and is often handled differently in real applications.

Should I use INNER JOIN or LEFT JOIN for a self join?

LEFT JOIN is usually safer for hierarchies, since it keeps rows that have no parent (like a top-level manager) instead of dropping them.

Is a self join slower than a normal join?

Not inherently — it performs like any other join of that table's size, though very deep hierarchies may need different techniques for good performance.

Key Takeaways

  • A self join connects a table to itself, typically to model hierarchical or comparative relationships.
  • Table aliases are required, since MySQL needs to tell the two references to the table apart.
  • LEFT JOIN is usually preferred for hierarchies, so top-level rows with no parent are not excluded.
  • The LEFT JOIN + IS NULL pattern still works with self joins to find rows with no match.
  • Self joins are used for org charts, category trees, and comparing rows within the same table.

Summary

A self join is not a different kind of join technically — it is an ordinary INNER JOIN or LEFT JOIN, just pointed at the same table twice with two clear aliases. It is the standard tool for hierarchical data like employees and managers.

In this lesson, you learned why aliases are required for a self join, worked through listing every employee with their manager's name, and saw a few other real-world uses for this pattern. Next, you will learn UNION and UNION ALL, which combine the results of separate queries instead of combining columns from related tables.

Lesson 51 Completed
  • You understand what a self join is and when it is needed.
  • You can alias a table twice to join it to itself.
  • You can list employees alongside their manager's name.
  • You are ready to learn UNION and UNION ALL.
Next Lesson →

UNION & UNION ALL