はじめに
SQLのテーブル結合については実務で使用しているため、ある程度理解しているつもりですが復習ついでに内部結合と外部結合の違いを整理してみました。
自分の頭の中をクリアにする目的もありますが、同じように「内部結合と外部結合の違いが曖昧…」という方の参考になれば嬉しいです。
テーブル結合とは
SQLにおけるテーブル結合とは、複数のテーブルを1つの表にまとめる操作のことです。
今回は基本的な3種類の結合パターンについて紹介します。
| 結合パターン | 説明 |
|---|---|
| 内部結合(INNER JOIN) | 共通のキーを持つ行のみを検索結果に含める |
| 左外部結合(LEFT OUTER JOIN) | 左側のテーブルを軸に、共通のキーを持たない行も検索結果に含める(右側は NULL で補完される) |
| 右外部結合(RIGHT OUTER JOIN) | 右側のテーブルを軸に、共通のキーを持たない行も検索結果に含める(左側は NULL で補完される) |
サンプルテーブル
次節では以下のサンプルテーブルに対して結合操作を行い、それぞれの結合パターンについて詳しく解説していきます。
| 社員ID | 社員名 | 支店ID |
|---|---|---|
| A001 | 虎杖悠仁 | 01 |
| A002 | 秤金次 | 02 |
| A003 | 禪院真希 | 04 |
| 支店ID | 支店名 |
|---|---|
| 01 | 東京第一 |
| 02 | 東京第二 |
| 03 | 仙台 |
内部結合(INNER JOIN)
SELECT 社員.社員ID, 社員.社員名, 社員.支店ID, 支店.支店名
FROM 社員テーブル 社員
INNER JOIN 支店テーブル 支店 ON 社員.支店ID = 支店.支店ID;
上記のSQLを実行した場合、検索結果は以下の通りです。
| 社員ID | 社員名 | 支店ID | 支店名 |
|---|---|---|---|
| A001 | 虎杖悠仁 | 01 | 東京第一 |
| A002 | 秤金次 | 02 | 東京第二 |
内部結合では共通のキーを持つ行のみが検索結果に含まれるため、支店テーブルに存在する支店IDを持つ虎杖悠仁、秤金次の2名が取得されます。
左外部結合(LEFT OUTER JOIN)
SELECT 社員.社員ID, 社員.社員名, 社員.支店ID, 支店.支店名
FROM 社員テーブル 社員
LEFT OUTER JOIN 支店テーブル 支店 ON 社員.支店ID = 支店.支店ID;
上記のSQLを実行した場合、検索結果は以下の通りです。
| 社員ID | 社員名 | 支店ID | 支店名 |
|---|---|---|---|
| A001 | 虎杖悠仁 | 01 | 東京第一 |
| A002 | 秤金次 | 02 | 東京第二 |
| A003 | 禪院真希 | 04 | NULL |
左外部結合では左側のテーブル(社員テーブル)を軸に、共通のキーを持たない行も検索結果に含めるため、虎杖悠仁、秤金次の2名に加え支店テーブルには存在しない支店IDを持つ禪院真希も取得されます。そして、禪院真希のレコードは支店名がNULLで補完されていることがわかります。
右外部結合(RIGHT OUTER JOIN)
SELECT 社員.社員ID, 社員.社員名, 社員.支店ID, 支店.支店名
FROM 社員テーブル 社員
RIGHT OUTER JOIN 支店テーブル 支店 ON 社員.支店ID = 支店.支店ID;
上記のSQLを実行した場合、検索結果は以下の通りです。
| 社員ID | 社員名 | 支店ID | 支店名 |
|---|---|---|---|
| A001 | 虎杖悠仁 | 01 | 東京第一 |
| A002 | 秤金次 | 02 | 東京第二 |
| NULL | NULL | NULL | 仙台 |
右外部結合では右側のテーブル(支店テーブル)を軸に、共通のキーを持たない行も検索結果に含めるため、東京第一、東京第二の2つの支店に加え社員テーブルには存在しない支店IDを持つ仙台支店も取得されます。そして、仙台支店のレコードは社員ID、社員名、支店IDがNULLで補完されていることがわかります。
まとめ
今回紹介した3種類の結合パターンは以下の2点を押さえるだけで整理できます。
- 「一致しない行を残すかどうか」
- 「どちらのテーブルを基準にするか」
特に実務ではINNER JOINとLEFT OUTER JOINの2つを使う場面が圧倒的に多いため、この違いを理解しておくとSQLの読み書きがぐっと楽になります。