SQLで複数のテーブルからデータを取得する際、テーブル結合が利用されます。
テーブル結合にはいくつかの種類が存在し、中でも頻繁に利用される3種類の結合方法をご紹介しながら、それぞれの違いについて確認していきたいと思います。
目次
SQL結合の種類1:内部結合(INNER JOIN)
1つ目に紹介するのが、双方のテーブルで結合条件に合致するデータのみを抽出することが可能な「内部結合(INNER JOIN)」です。
基本構文
内部結合SQLの基本構文は下記となります。
SELECT カラム名[, カラム名, ...] FROM テーブル名1 [INNER] JOIN テーブル名2 ON テーブル名2.カラム名 = テーブル名1.カラム名 [WHERE 条件式];
ON句に指定する結合条件は、どちらのテーブルを先に指定するといった決まりはありません。
サンプル
今回のサンプルデータは「office」テーブルと「region」テーブルをそれぞれ下記のデータで用意しました。
office
+------+--------------------+-----------+ | id | office_name | region_id | +------+--------------------+-----------+ | 1 | 新宿支店 | 3 | | 2 | 渋谷支店 | 3 | | 3 | 函館支店 | 1 | | 4 | 梅田支店 | 5 | | 5 | 那覇支店 | 9 | | 6 | ソウル支店 | 99 | | 7 | バンコク支店 | 99 | +------+--------------------+-----------+
region
+------+-------------+ | id | region_name | +------+-------------+ | 1 | 北海道 | | 2 | 東北 | | 3 | 関東 | | 4 | 中部 | | 5 | 近畿 | | 6 | 中国 | | 7 | 四国 | | 8 | 九州 | | 9 | 沖縄 | +------+-------------+
では実際に内部結合を試してみましょう。
SELECT * FROM office INNER JOIN region ON region.id = office.region_id;
実行した結果が下記となります。
+------+--------------+-----------+------+-------------+ | id | office_name | region_id | id | region_name | +------+--------------+-----------+------+-------------+ | 3 | 函館支店 | 1 | 1 | 北海道 | | 1 | 新宿支店 | 3 | 3 | 関東 | | 2 | 渋谷支店 | 3 | 3 | 関東 | | 4 | 梅田支店 | 5 | 5 | 近畿 | | 5 | 那覇支店 | 9 | 9 | 沖縄 | +------+--------------+-----------+------+-------------+
結合条件に指定した「office」テーブルの「region_id」と「region」テーブルの「id」が一致するデータのみが抽出出来ていることが確認出来ます。
officeテーブルの「ソウル支店」や「バンコク支店」に設定された「region_id=99」は「region」テーブルに存在しないため取得されていません。
反対に、regionテーブルの「東北」「中部」などのデータも、「office」テーブルに一致するデータが存在しないため取得されません。
SQL結合の種類2: 外部結合(OUTER JOIN)
2つ目に紹介するのが、軸となるテーブルデータを全て取得した上で、結合条件に一致するデータをもう一方のテーブルから取得する「外部結合(OUTER JOIN」です。
外部結合には「左外部結合(LEFT OUTER JOIN)」と「右外部結合(RIGHT OUTER JOIN)」が存在します。
完全外部結合(FULL OUTER JOIN)と呼ばれる、結合条件に関係なく双方のテーブルからデータを取得する外部結合も存在しますが、あまり利用されないため説明は省略させて頂きます。
左外部結合(LEFT OUTER JOIN)
まずは左外部結合の基本構文から確認していきましょう。
SELECT カラム名[, カラム名, ...] FROM テーブル名1 LEFT[OUTER] JOIN テーブル名2 ON テーブル名2.カラム名 = テーブル名1.カラム名 [WHERE 条件式];
左外部結合では、テーブル名1に記述したテーブルが軸となり、テーブル名2が結合先のテーブルとなります。
サンプル
では実際にサンプルの「office」と「region」テーブルで左外部結合を行い取得結果を確認してみましょう。
SELECT * FROM office LEFT JOIN region ON region.id = office.region_id;
実行した結果が下記となります。
+------+--------------------+-----------+------+-------------+ | id | office_name | region_id | id | region_name | +------+--------------------+-----------+------+-------------+ | 3 | 函館支店 | 1 | 1 | 北海道 | | 1 | 新宿支店 | 3 | 3 | 関東 | | 2 | 渋谷支店 | 3 | 3 | 関東 | | 4 | 梅田支店 | 5 | 5 | 近畿 | | 5 | 那覇支店 | 9 | 9 | 沖縄 | | 6 | ソウル支店 | 99 | NULL | NULL | | 7 | バンコク支店 | 99 | NULL | NULL | +------+--------------------+-----------+------+-------------+
内部結合の場合と異なり、regionテーブルにidが存在しない「ソウル支店」や「バンコク支店」のデータも取得出来ていることをご確認頂けます。
外部結合では結合先のデータが存在しない場合、サンプルのようにカラムの値としては「NULL」が表示されます。
右外部結合(RIGHT OUTER JOIN)
次に右外部結合の基本構文です。
SELECT カラム名[, カラム名, ...] FROM テーブル名1 RIGHT[OUTER] JOIN テーブル名2 ON テーブル名2.カラム名 = テーブル名1.カラム名 [WHERE 条件式];
右外部結合では、テーブル名2に指定したテーブルが軸に変わります。
サンプル
右外部結合でSQLを実行すると取得結果がどのように変わるのか確認していきましょう。
SELECT * FROM office RIGHT JOIN region ON region.id = office.region_id;
実行した結果が下記となります。
+------+--------------+-----------+------+-------------+ | id | office_name | region_id | id | region_name | +------+--------------+-----------+------+-------------+ | 1 | 新宿支店 | 3 | 3 | 関東 | | 2 | 渋谷支店 | 3 | 3 | 関東 | | 3 | 函館支店 | 1 | 1 | 北海道 | | 4 | 梅田支店 | 5 | 5 | 近畿 | | 5 | 那覇支店 | 9 | 9 | 沖縄 | | NULL | NULL | NULL | 2 | 東北 | | NULL | NULL | NULL | 4 | 中部 | | NULL | NULL | NULL | 6 | 中国 | | NULL | NULL | NULL | 7 | 四国 | | NULL | NULL | NULL | 8 | 九州 | +------+--------------+-----------+------+-------------+
今度は軸となるregionテーブルに設定された値が全て取得された上で、結合条件に合致するofficeテーブルの値を取得していることが分かります。
SQL結合の種類3: クロス結合(CROSS JOIN)
3つ目のクロス結合は、結合するテーブルの全ての組み合わせでデータを取得する方法です。
「テーブル名1 × テーブル名2」の行数が取得結果として返却されます。
SQLの結合の種類としては、よく紹介されるクロス結合ですが、実務において利用されることはほとんどありません。
基本構文
クロス結合の基本構文は下記となります。
SELECT カラム名[, カラム名, ...] FROM テーブル名1 CROSS JOIN テーブル名2 [WHERE 条件式];
全ての組み合わせを取得するため、ON句による結合条件は指定しません。
サンプル
実際にサンプルデータを利用して取得結果を確認してみましょう。
SELECT * FROM office CROSS JOIN region;
実行した結果はofficeテーブル7行 × regionテーブル9行の63行が返却されます。
+------+--------------------+-----------+------+-------------+ | id | office_name | region_id | id | region_name | +------+--------------------+-----------+------+-------------+ | 1 | 新宿支店 | 3 | 1 | 北海道 | | 2 | 渋谷支店 | 3 | 1 | 北海道 | | 3 | 函館支店 | 1 | 1 | 北海道 | | 4 | 梅田支店 | 5 | 1 | 北海道 | | 5 | 那覇支店 | 9 | 1 | 北海道 | | 6 | ソウル支店 | 99 | 1 | 北海道 | | 7 | バンコク支店 | 99 | 1 | 北海道 | ・・・・・・・・・・・・・・・・ ・・・・・・・・・・・・・・・・・・・・ | 1 | 新宿支店 | 3 | 2 | 東北 | | 2 | 渋谷支店 | 3 | 2 | 東北 | | 5 | 那覇支店 | 9 | 9 | 沖縄 | | 6 | ソウル支店 | 99 | 9 | 沖縄 | | 7 | バンコク支店 | 99 | 9 | 沖縄 | +------+--------------------+-----------+------+-------------+ 63 rows in set (0.02 sec)
取得結果が多いため、省略して掲載しています。
さいごに:SQL結合の種類を把握して適切な使い方を選択しよう!
本記事では、SQL結合の種類とそれぞれの利用方法についてご紹介してきました。
実務で一般的に利用されるのは「内部結合(INNER JOIN)」と「左外部結合(LEFT OUTER JOIN)」の2つです。
まずは内部結合と外部結合の違いをしっかりと理解した上で、状況に応じて他のテーブル結合の種類も覚えていくのが良いかと思います。
外部結合とクロス結合のサンプルでも上記データを利用します。