Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

SELF JOIN

同じテーブルを別名を付けて2つに見立て、自分自身と結合する手法です。階層データの親子関係の取得や、隣接する行の比較などに使われます。

構文
-- 同じテーブルに異なるエイリアスを付けて結合します。
SELECT a.列名, b.列名
FROM テーブル AS a
JOIN テーブル AS b ON a.結合キー = b.結合キー;
構文一覧
構文概要
FROM テーブル AS a JOIN テーブル AS b同じテーブルに異なるエイリアスを付けて自己結合します。
ON a.上司ID = b.社員ID親子関係や参照関係を結合条件に指定します。
サンプルコード
-- 社員テーブルで部下とその上司名を取得します。
SELECT
    emp.社員名 AS 社員名,
    mgr.社員名 AS 上司名
FROM 社員 AS emp
LEFT JOIN 社員 AS mgr ON emp.上司ID = mgr.社員ID;

-- 同じ部署の社員同士のペアを列挙します(重複を避けるため社員IDで順序を制限)。
SELECT
    a.社員名 AS 社員A,
    b.社員名 AS 社員B,
    a.部署名
FROM 社員 AS a
JOIN 社員 AS b
    ON a.部署名 = b.部署名
    AND a.社員ID < b.社員ID
ORDER BY a.部署名, a.社員ID;
実行結果
-- 上司名の取得結果(上司を持たない場合は NULL)。
社員名     | 上司名
-----------+-----------
山田 太郎  | NULL
鈴木 花子  | 山田 太郎
佐藤 次郎  | 山田 太郎
田中 恵    | 鈴木 花子

-- 同じ部署の社員ペア。
社員A      | 社員B      | 部署名
-----------+------------+----------
鈴木 花子  | 佐藤 次郎  | 営業部
データベース別の書き方

自己結合の構文は主要なデータベースで共通して使用できます。

-- MySQL・PostgreSQL・SQL Server・Oracle・SQLite 共通
SELECT emp.社員名 AS 社員名, mgr.社員名 AS 上司名
FROM 社員 AS emp
LEFT JOIN 社員 AS mgr ON emp.上司ID = mgr.社員ID;

Oracle では『AS』キーワードをテーブルエイリアスに使えません。エイリアスを付ける際は『AS』を省略して記述します。

-- Oracle ではテーブルエイリアスに AS を使わない
SELECT emp.社員名 AS 社員名, mgr.社員名 AS 上司名
FROM 社員 emp
LEFT JOIN 社員 mgr ON emp.上司ID = mgr.社員ID;
概要

『SELF JOIN』はSQLの特別な構文ではなく、通常の JOIN を同じテーブルに対して適用する手法です。テーブルエイリアスを必ず付けないと列の参照が曖昧になりエラーになるため、必ずエイリアスを指定してください。

主な用途は次の2つです。1つ目は「社員と上司」「カテゴリと親カテゴリ」のような階層データの親子関係の取得です。2つ目は同じテーブル内の行同士を比較する場面(同一部署の社員ペア・連続する日付の売上比較など)です。

親が存在しない行(トップレベルの社員など)も含めたい場合は『LEFT JOIN』を使うと NULL として取得できます。CROSS JOIN との違いは『CROSS JOIN』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。