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.
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.
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.
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.
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.
Both open a third-party SQL playground in a new tab. External site terms and privacy policy apply.