自己結合で同じテーブル同士を結合する
自己結合(セルフジョイン)は、同じテーブルを 2 回使って結合するテクニックです。階層構造やペア関係を表現するときに使います。
基本的な考え方
同じテーブルに別名をつけて、あたかも 2 つのテーブルがあるかのように JOIN します。
SELECT ...
FROM テーブル名 a
JOIN テーブル名 b ON 条件;具体例:上司と部下
employees テーブルに manager_id という、上司の社員 ID を持つカラムがあるとします。
-- employees テーブル
-- id, name, manager_id
-- 1, 社長, NULL
-- 2, 部長, 1
-- 3, 課長, 2
-- 4, 田中, 3社員名と上司名を一緒に取得するには、こう書きます。
SELECT
e.name AS employee_name,
m.name AS manager_name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;結果は次のようになります。
| employee_name | manager_name |
|---|---|
| 社長 | NULL |
| 部長 | 社長 |
| 課長 | 部長 |
| 田中 | 課長 |
employees テーブルを e(社員)と m(上司)という 2 つの役割で使っています。
なぜ LEFT JOIN を使うか
社長のように上司がいない人は manager_id が NULL です。INNER JOIN を使うと社長が結果から消えてしまいます。全員を取得したい場合は LEFT JOIN を使います。
INNER JOIN
上司がいない人が結果に出てこない
LEFT JOIN
上司がいない人も含めて取得できる
具体例:カテゴリの親子関係
categories テーブルで親カテゴリを表現するケースもよくあります。
-- categories テーブル
-- id, name, parent_id
-- 1, 電化製品, NULL
-- 2, スマートフォン, 1
-- 3, パソコン, 1
-- 4, iPhone, 2SELECT
c.name AS category,
p.name AS parent_category
FROM categories c
LEFT JOIN categories p ON c.parent_id = p.id;具体例:同僚を見つける
同じ部署の他の社員を見つけることもできます。
SELECT
a.name AS employee1,
b.name AS employee2
FROM employees a
JOIN employees b ON a.department_id = b.department_id AND a.id < b.id;a.id < b.id をつけることで、同じペアが 2 回出てくるのを防いでいます。
注意点
自己結合では必ず別名をつけてください。同じテーブル名が 2 回出てくると、どちらのカラムか区別できなくなります。
-- エラーになる(どっちの id かわからない)
SELECT name FROM employees JOIN employees ON manager_id = id;
-- 正しい(別名で区別)
SELECT e.name FROM employees e JOIN employees m ON e.manager_id = m.id;自己結合は最初は混乱しやすいですが、「同じテーブルを 2 つの役割で使う」と考えるとわかりやすくなります。











