言語
日本語
English

Caution

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

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

FULL OUTER JOIN

対応: SQL-92(1992)

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

構文

『FULL OUTER JOIN』(PostgreSQL で使用可能)。

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)。

サンプルコード

以下の『employees』テーブルと『departments』テーブルを例に説明します。

employees id name department_id salary 1 八神庵 1 300000 2 草薙京 2 280000 3 テリー・ボガード NULL 260000 3 rows in set

departments id department_name 1 八神流古武術 2 草薙流古武術 3 サウスタウン 3 rows in set

社員と部署を結合します。部署未設定の社員も、社員のいない部署も含みます(PostgreSQL)。

sample_full_outer_join.sql
SELECT e.name, d.department_name
FROM employees AS e
FULL OUTER JOIN departments AS d ON e.department_id = d.id;
+------------------+------------------+
| name             | department_name  |
+------------------+------------------+
| 八神庵           | 八神流古武術     |
| 草薙京           | 草薙流古武術     |
| テリー・ボガード | NULL             |
| NULL             | サウスタウン     |
+------------------+------------------+
4 rows in set

MySQL での代替:『LEFT JOIN』と『RIGHT JOIN』を『UNION』で結合します。

sample_full_outer_join.sql
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;
+------------------+------------------+
| name             | department_name  |
+------------------+------------------+
| 八神庵           | 八神流古武術     |
| 草薙京           | 草薙流古武術     |
| テリー・ボガード | NULL             |
| NULL             | サウスタウン     |
+------------------+------------------+
4 rows in set

どちらかのテーブルにしか存在しない行(非一致行)のみを取得します(PostgreSQL)。

sample_full_outer_join.sql
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;
+------------------+-----------------+
| name             | department_name |
+------------------+-----------------+
| テリー・ボガード | NULL            |
| NULL             | サウスタウン    |
+------------------+-----------------+
2 rows in set

データベース別の書き方

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

-- PostgreSQL
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(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;

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』も合わせて参照してください。

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