DevLearningTools

LEARN · SQL

SQL SELF JOIN

A self join joins a table to itself, used to compare rows within the same table, like pairing every employee with their own manager.

Every join so far has combined two different tables. A self join combines a table with itself, genuinely useful whenever one row needs to reference another row in the exact same table, like employees.manager_id pointing back at another row in employees.

Learning Objectives

  • Recognize when a self-referencing column (like manager_id) calls for a self join.
  • Write a self join using two different aliases for the same table.
  • Use LEFT JOIN in a self join to include rows with no self-match, like a CEO with no manager.

employees AS e

The employee

JOIN employees AS m

ON e.manager_id = m.id

employees AS m

Same table, the manager row

Result

Employee name next to their manager's name

Pairing Employees With Their Manager

employees is named twice, aliased as e (the employee being looked at) and m (whoever that employee's manager_id points to). Two different aliases for the same table are exactly what makes this a self join rather than a regular join, SQL itself doesn't need a special keyword for it, it's just an ordinary JOIN where the table on both sides happens to be the same one.

MySQL / MariaDB / PostgreSQL / SQLite / SQL Server / Oracle
SELECT e.first_name AS employee_name, m.first_name AS manager_name
FROM employees e
JOIN employees m ON e.manager_id = m.id;

Including Employees With No Manager

Plain JOIN here would silently drop whoever has a NULL manager_id, typically the one person at the top with no manager at all. LEFT JOIN keeps that row, showing manager_name as NULL for them instead of removing them from the result entirely, the exact same NULL-preserving behavior covered in the LEFT JOIN lesson, just applied to a table joined with itself.

MySQL / MariaDB / PostgreSQL / SQLite / SQL Server / Oracle
SELECT e.first_name AS employee_name, m.first_name AS manager_name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

Finding Everyone Who Shares a Manager

This pairs up every two employees who report to the same manager. e1.id < e2.id is there specifically to avoid listing both (Ada, Grace) and (Grace, Ada) as two separate rows, and to stop an employee from being paired with themselves, a common self-join pattern worth recognizing even if its exact use here is secondary to the manager-pairing example above.

MySQL / MariaDB / PostgreSQL / SQLite / SQL Server / Oracle
SELECT e1.first_name AS employee_1, e2.first_name AS employee_2
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.manager_id
WHERE e1.id < e2.id;

Try It Yourself

Write a query listing every employee's name next to their manager's name, including anyone with no manager.

Answer
SELECT e.first_name AS employee_name, m.first_name AS manager_name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

Frequently Asked Questions

Is SELF JOIN its own keyword in SQL?

No, there's no SELF JOIN keyword, it's an ordinary JOIN (or LEFT JOIN) where the same table is listed on both sides with two different aliases. "Self join" describes the pattern, not special syntax.

Does a self join always need table aliases?

Yes, always, without two different aliases SQL has no way to tell which employees.first_name in the SELECT list refers to the employee and which refers to the manager, both would just say employees.

Common Beginner Mistakes

Forgetting aliases and writing employees.manager_id = employees.id

This is ambiguous, or an outright error in most databases, SQL can't tell the two employees references apart. Both occurrences of the table need their own alias, as in every example above.

Using JOIN instead of LEFT JOIN and losing whoever has no manager

A plain JOIN self-join silently excludes anyone with a NULL manager_id, exactly the same unmatched-row behavior as a regular JOIN between two different tables. LEFT JOIN is needed to keep them.

Best Practices

  • Always alias both sides of a self join, there's no way to write one correctly without aliases.
  • Choose aliases that describe the role (e / m for employee / manager), not just arbitrary letters, for a reader scanning the query later.
  • Use LEFT JOIN rather than plain JOIN whenever rows with no self-match (like a top-level manager) need to stay in the result.

Interview Questions

What is a self join and when would you use one?

A self join is a regular join where a table is joined to itself, using two different aliases to tell the two "copies" apart. It's used whenever a row references another row in the same table, the classic example being an employees table where manager_id points to another row's id in that same table.

Write a self join that lists each employee's name next to their manager's name, including employees with no manager.

SELECT e.first_name AS employee_name, m.first_name AS manager_name FROM employees e LEFT JOIN employees m ON e.manager_id = m.id; — LEFT JOIN specifically, so a NULL manager_id (no manager) still produces a row instead of being silently dropped.

Summary

A self join joins a table to itself using two different aliases, the standard way to work with a self-referencing column like manager_id. LEFT JOIN keeps rows with no self-match, like whoever has no manager at all.

What's Next?

That completes Module 4, Joins: why Beacon Robotics' schema normalized into separate tables, INNER/LEFT/RIGHT/FULL JOIN, and self joins. Module 5, Combining and Grouping, is next, starting with UNION, the exact tool used to simulate FULL JOIN a few lessons back, now covered properly on its own.

</>

Ready to Practice SQL?

Write and run real SQL queries online, right in your browser, no install or signup required. Pick a playground based on which database you want to practice on.

SQLite / PostgreSQL

Fast, no server, no ads.

Open DB Fiddle ↗

MySQL / SQL Server

Switch databases with one dropdown.

Open SQL Fiddle ↗

Both open a third-party SQL playground in a new tab. External site terms and privacy policy apply.