Caution

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

FULL OUTER JOIN

両テーブルの全行を保持して結合する方法です。どちらかのテーブルにしか存在しない行も結果に含まれます。

構文
-- FULL OUTER JOIN(PostgreSQL・SQL Server・Oracle で使用可能)。
SELECT 列名 FROM テーブル1
FULL OUTER JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列;

-- MySQL では FULL OUTER JOIN が未対応のため、UNION で代替します。
SELECT 列名 FROM テーブル1
LEFT JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列
UNION
SELECT 列名 FROM テーブル1
RIGHT JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列;
結合種別の比較
結合種別左テーブルのみ両方一致右テーブルのみ
INNER JOIN含まない。含む。含まない。
LEFT JOIN含む(右側はNULL)。含む。含まない。
RIGHT JOIN含まない。含む。含む(左側はNULL)。
FULL OUTER JOIN含む(右側はNULL)。含む。含む(左側はNULL)。
サンプルコード
-- PostgreSQL / SQL Server / Oracle での FULL OUTER JOIN の例。
-- 社員と部署を結合します。部署未設定の社員も、社員のいない部署も含みます。
SELECT e.name, d.department_name
FROM employees AS e
FULL OUTER JOIN departments AS d ON e.department_id = d.id;

-- MySQL での代替:LEFT JOIN と RIGHT JOIN を UNION で結合します。
SELECT e.name, d.department_name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
UNION
SELECT e.name, d.department_name
FROM employees AS e
RIGHT JOIN departments AS d ON e.department_id = d.id;

-- 両テーブルにしか存在しない行(非一致行)のみを取得します。
-- PostgreSQL での例。
SELECT e.name, d.department_name
FROM employees AS e
FULL OUTER JOIN departments AS d ON e.department_id = d.id
WHERE e.id IS NULL OR d.id IS NULL;
実行結果
-- FULL OUTER JOIN の結果例
-- +----------+------------------+
-- | name     | department_name  |
-- +----------+------------------+
-- | 田中太郎 | 開発部           | ← 両テーブルに存在
-- | 鈴木花子 | 営業部           | ← 両テーブルに存在
-- | 高橋美咲 | NULL             | ← 社員テーブルのみ(部署未設定)
-- | NULL     | 法務部           | ← 部署テーブルのみ(社員なし)
-- +----------+------------------+
データベース別の書き方

PostgreSQL・SQL Server・Oracle は『FULL OUTER JOIN』をそのまま使用できます。

-- PostgreSQL・SQL Server・Oracle
SELECT e.name, d.department_name
FROM employees AS e
FULL OUTER JOIN departments AS d ON e.department_id = d.id;

MySQL は『FULL OUTER JOIN』に対応していません。『LEFT JOIN』と『RIGHT JOIN』を『UNION』で組み合わせて代替します。

-- MySQL での代替方法
SELECT e.name, d.department_name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
UNION
SELECT e.name, d.department_name
FROM employees AS e
RIGHT JOIN departments AS d ON e.department_id = d.id;

SQLite も『FULL OUTER JOIN』に対応していません(3.39.0 以降で対応)。古いバージョンでは MySQL と同様に『LEFT JOIN』の『UNION』で代替してください。ただし SQLite は『RIGHT JOIN』も 3.39.0 以降のため、それ以前のバージョンではテーブルの順序を入れ替えた2つの『LEFT JOIN』を『UNION』します。

-- SQLite(3.39.0 未満)での代替方法
SELECT e.name, d.department_name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
UNION
SELECT e.name, d.department_name
FROM departments AS d
LEFT JOIN employees AS e ON e.department_id = d.id;
概要

『FULL OUTER JOIN』は両テーブルのすべての行を保持する結合で、データ整合性の確認(孤立レコードの検出)や2つのデータセットの差分確認などに使用されます。

MySQLはFULL OUTER JOINに対応していません。MySQLで同等の結果を得るには、LEFT JOINとRIGHT JOINを『UNION』(重複除去あり)または『UNION ALL』(重複保持)で組み合わせる必要があります。UNION ALLを使う場合は手動で重複を除去するか、UNION(重複除去)を使用してください。

各テーブルに対応行がない部分はNULLになります。『IS NULL / IS NOT NULL』と組み合わせることで、どちらかのテーブルにしか存在しない行を特定できます。JOINの種類については『INNER JOIN』・『LEFT JOIN / RIGHT JOIN』も合わせて参照してください。

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