同じテーブル同士を結合 - 自己結合 (Self Join)
同じテーブルを別エイリアスで結合する手法。組織図や行同士の比較に使う
概念図
構文
sql
SELECT ... FROM t a JOIN t b ON a.key = b.other_keyサンプル
社員テーブル自身を結合し、各社員と上司の名前を並べて取得する
sql
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;自己結合とは
自己結合は 同じテーブルを別エイリアスで 2 回使う結合です。SQL には「自己結合」という専用構文はなく、ただ同じテーブルに別名を付けて JOIN するだけです。
同じテーブル内の行同士を関連付けたいときに使います: 組織の階層(社員と上司)、連続する行の差分、自分より前の行との比較など。
組織図(manager_id パターン)
社員テーブルが自身の主キー id を指す manager_id を持つとき、自己結合で社員と上司を並べて取得できます。上司がいない(社長などの)行も残したければ LEFT JOIN を使います。
sql
SELECT e.id, e.name, m.name AS manager_name
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id
ORDER BY m.name NULLS FIRST, e.name;行同士の比較
同じテーブルの別の行と値を比較したい場合にも使えます。たとえば「自分と同じ部署にいる別の社員」を列挙するには、自身を除外する条件(a.id <> b.id)を ON または WHERE に書きます。
sql
SELECT a.name AS employee, b.name AS coworker
FROM employees a
JOIN employees b
ON b.department_id = a.department_id
AND b.id <> a.id;ウィンドウ関数との使い分け
前後行との比較や累計のような処理は、自己結合よりも LAG / LEAD / SUM() OVER(...) などのウィンドウ関数のほうが簡潔で高速なことが多いです。階層の再帰的な展開には再帰 CTEを検討します。
落とし穴
- エイリアス忘れ: 同じテーブルを 2 回書くので、エイリアスなしでは列参照が曖昧になりエラー
- 自己一致の行:
a.id <> b.idのような自身除外条件を忘れると、全員が自分自身とペアになる行が混ざる - サイズの爆発: 結合条件が緩いと自己結合は行数が二乗に近づく。大きなテーブルでは要注意
