Query Go
同じテーブル同士を結合 - 自己結合 (Self Join) の使い方・オプション・サンプル

同じテーブル同士を結合 - 自己結合 (Self Join)

同じテーブルを別エイリアスで結合する手法。組織図や行同士の比較に使う

概念図

自己結合 (Self Join) diagram

構文

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 のような自身除外条件を忘れると、全員が自分自身とペアになる行が混ざる
  • サイズの爆発: 結合条件が緩いと自己結合は行数が二乗に近づく。大きなテーブルでは要注意

関連トピック