SQL Self Join Explained

โฑ๏ธ 35 sec read ๐Ÿ’พ SQL

A self join joins a table to itself, treating it as two copies with different aliases. It's the standard way to relate rows within one table โ€” an employee to their manager, or one row to its duplicate.

How Do You Join a Table to Itself?

List the table twice with two aliases and join them like any other pair of tables. The aliases are mandatory โ€” without them the database can't tell which copy a column refers to.

-- employees: id | name  | manager_id
--            1  | Dana  | NULL
--            2  | Ben   | 1
--            3  | Chris | 1
--            4  | Ana   | 2

SELECT e.name AS employee, m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;
-- employee | manager
-- Ben      | Dana
-- Chris    | Dana
-- Ana      | Ben

Mechanically this is a plain inner join; the only twist is that both sides are the same table.

How Do You Include Employees With No Manager?

Use a LEFT JOIN so rows without a match (the CEO) survive with a NULL manager.

SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
-- employee | manager
-- Dana     | NULL      <- kept by the LEFT JOIN
-- Ben      | Dana
-- ...

How Do You Find Duplicate Pairs With a Self Join?

Join the table to itself on the columns that define "duplicate," and use < on the primary key so each pair appears once instead of twice (and rows don't match themselves).

SELECT a.id, b.id, a.email
FROM users a
JOIN users b
  ON a.email = b.email
 AND a.id < b.id;        -- not <>, or you get each pair twice
-- id | id | email
-- 7  | 42 | [email protected]

For counting duplicates rather than pairing them, GROUP BY is simpler โ€” see counting duplicates in SQL.

Common Pitfalls

Pro Tip: Name self-join aliases after their role, not t1/t2. employees e JOIN employees m (employee/manager) makes the query self-documenting and prevents mixing up which side is which.

โ† Back to SQL Tips