言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

  1. トップページ
  2. SQL辞典
  3. SELF JOIN

SELF JOIN

対応: SQL-92(1992)

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

構文

同じテーブルに異なるエイリアスを付けて結合します。

SELECT a.column, b.column
FROM table AS a
JOIN table AS b ON a.join_key = b.join_key;

構文一覧

構文概要
FROM table AS a JOIN table AS b同じテーブルに異なるエイリアスを付けて自己結合します。
ON a.manager_id = b.employee_id親子関係や参照関係を結合条件に指定します。

サンプルコード

以下の『employees』テーブルを例に説明します。『manager_id』は同じテーブルの『employee_id』を参照しています。

employees employee_id name manager_id department 1 釘崎野薔薇 NULL 呪術高専 2 五条悟 1 呪術高専 3 虎杖悠仁 2 呪術高専 4 伏黒恵 2 呪術高専 4 rows in set

社員テーブルで部下とその上司名を取得します。

sample_self_join.sql
SELECT
    emp.name AS employee,
    mgr.name AS manager
FROM employees AS emp
LEFT JOIN employees AS mgr ON emp.manager_id = mgr.employee_id;
+------------+------------+
| employee   | manager    |
+------------+------------+
| 釘崎野薔薇 | NULL       |
| 五条悟     | 釘崎野薔薇 |
| 虎杖悠仁   | 五条悟     |
| 伏黒恵     | 五条悟     |
+------------+------------+
4 rows in set

同じ部署の社員同士のペアを列挙します(重複を避けるため employee_id で順序を制限)。

sample_self_join.sql
SELECT
    a.name AS employee_a,
    b.name AS employee_b,
    a.department
FROM employees AS a
JOIN employees AS b
    ON a.department = b.department
    AND a.employee_id < b.employee_id
ORDER BY a.department, a.employee_id;
+------------+------------+------------+
| employee_a | employee_b | department |
+------------+------------+------------+
| 釘崎野薔薇 | 五条悟     | 呪術高専   |
| 釘崎野薔薇 | 虎杖悠仁   | 呪術高専   |
| 釘崎野薔薇 | 伏黒恵     | 呪術高専   |
| 五条悟     | 虎杖悠仁   | 呪術高専   |
| 五条悟     | 伏黒恵     | 呪術高専   |
| 虎杖悠仁   | 伏黒恵     | 呪術高専   |
+------------+------------+------------+
6 rows in set

データベース別の書き方

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

-- MySQL・PostgreSQL・SQLite 共通
SELECT emp.name AS employee, mgr.name AS manager
FROM employees AS emp
LEFT JOIN employees AS mgr ON emp.manager_id = mgr.employee_id;

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

-- Oracle ではテーブルエイリアスに AS を使わない
SELECT emp.name AS employee, mgr.name AS manager
FROM employees emp
LEFT JOIN employees mgr ON emp.manager_id = mgr.employee_id;

概要

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

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

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

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