リレーショナルデータベースの基礎を学ぶ際に、多くの方がもやもやを抱えやすいのが外部結合と内部結合の違いについてかと思います。今回は、リレーショナルデータベースの3つの基本操作から始まり、結合方法の種類と違いについてご紹介したいと思います。
目次
2.1 内部結合とは
2.2 MySQLを使用する場合の内部結合の構文例
3.1 外部結合とは
3.2 OUTER JOINはLEFT・RIGHT・FULLの3種類
3.3 MySQLを使用する場合の内部結合の構文例
1.リレーショナルデータベースの3つの基本操作
リレーショナルデータベースの表操作には、主に3つの操作があります。それは「選択(SELECTION)」「射影(PROJECTION)」「結合(JOIN)」です。
1.1 選択とは
選択とは、表(テーブル)の中から指定した条件に沿った「行(レコード)」を抽出する操作のことです。
上図のように社員一覧から開発課に所属する社員のレコードのみを抽出する場合、SQLは次のように書くことができます。
SELECT * FROM 社員一覧 WHERE 所属部署 = '開発課'; (※注1)
(※注1)「*」とは
「*」は「対象テーブルの全カラム名」を示します。今回は「社員番号, 氏名, 等級, 所属部署」と記載するのと同等の扱いになります。
1.2 射影とは
射影とは、表の中から指定した条件に沿った「列(カラム)」を抽出する操作のことです。
上図のように社員一覧から指名と所属部署に属するデータのみを抽出する場合、SQLは次のように書くことができます。
SELECT 氏名, 所属部署 FROM 社員一覧;
1.3 結合とは
結合とは、2つ以上の表(テーブル)を共通の値を持つ列(カラム)をキーに、くっつけて一つの表にしてしまうことです。
上図のように「所属部署」をキーに「社員一覧」と「部署マスタ」を結合する場合、SQLは次のように書くことができます。
SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
部署マスタ.所属部署, 部署マスタ.部署名称
FROM 社員一覧, 部署マスタ
WHERE 社員一覧.所属部署 = 部署マスタ.所属部署;
対象となるテーブルが1つだけだった選択や射影と違い、結合の場合はどちらのテーブルに属するカラム名かを特定するために「テーブル名.カラム名」と書く必要があります。
ちなみに、社員一覧の「所属部署」と、部署マスタの「所属部署」は、それぞれカラム名が異なっていても結合することが可能です。さらにSELECTの後の要素の指定を「*」にした場合、FROMの後に書かれた順に全ての要素が羅列されます。
カラム名が異なり、かつ「*」を指定した場合は、次のようなSQLとその実行結果になります。
SELECT *
FROM 社員一覧, 部署マスタ
WHERE 社員一覧.所属部署 = 部署マスタ.所属コード;
今回の記事ではこの「結合」をメインに、さらに掘り下げていきたいと思います。
2.内部結合(INNER JOIN)の概要と書き方
2.1 内部結合とは
実は、前述した「結合(JOIN)」と「内部結合(INNER JOIN)」の実行結果は、全く同じになります。内部結合は記述を省略することが可能で、省略したものが先ほど「結合」の項目でご紹介した記述例のようなSQLになります。
なお内部結合(INNER JOIN)には、「指定したカラムの値が一致するレコードのみを抽出する」という特徴があります。つまり、どちらかにないレコードは抽出対象になりません。(もちろん同じ結果が得られる「結合」でも、一致しないレコードがあれば結果に抽出されないのは一緒です)
2.2 MySQLを使用する場合の内部結合の構文例
省略せずに内部結合としてきちんと記述した場合、次のようになります。(なお今回MySQLを例にとっていますが、このあたりは基本のため多くのRDBMSで同じ構文が使用可能です)
SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
部署マスタ.所属コード, 部署マスタ.部署名称
FROM 社員一覧
INNER JOIN 部署マスタ
ON 社員一覧.所属部署 = 部署マスタ.所属コード;
このように、「所属部署」の値が「部署マスタ」に存在しない「社員E」のレコードは、内部結合では抽出対象外になります。
3.外部結合(OUTER JOIN)の概要と書き方
3.1 外部結合とは
一致するもののみを対象とする内部結合に対し、外部結合は一致するものがないレコードも抽出対象とすることが可能です。
3.2 OUTER JOINはLEFT・RIGHT・FULLの3種類
外部結合には、「LEFT OUTER JOIN」と「RIGHT OUTER JOIN」「FULL OUTER JOIN」の3種類があります。
■LEFT OUTER JOINとは
LEFT OUTER JOINでは、2つのテーブルのうち「FROM」で指定した方のテーブルを基準として、「JOIN」で指定した方のテーブルのうち該当レコードをくっつけるという処理を行います。
■RIGHT OUTER JOINとは
RIGHT OUTER JOINでは、2つのテーブルのうち「JOIN」で指定した方のテーブルを基準として、「FROM」で指定した方のテーブルのうち該当レコードをくっつけるという処理を行います。テーブルの指定が逆になるだけ(テーブルを入れ替えたら同じ結果になる)なので、一般的にLEFT OUTER JOINを利用するケースが大半です。
■FULL OUTER JOINとは
FULL OUTER JOINでは、2つのテーブルにある全てのレコードを抽出対象とします。お互いに存在しない部分には、「NULL」が入ります。
■LEFT OUTER JOINの場合
LEFT OUTER JOINでテーブルを抽出するSQLを書くと、次のようになります。
SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
部署マスタ.所属部署, 部署マスタ.部署名称
FROM 社員一覧
LEFT OUTER JOIN 部署マスタ
ON 社員一覧.所属部署 = 部署マスタ.所属部署;
このように「社員一覧」のレコードは全て抽出対象となり、取得できなかった「社員E」に対応する「部署コード」と「部署名称」の空欄は、NULLで埋められました。
■RIGHT OUTER JOINの場合
RIGHT OUTER JOINでテーブルを抽出するSQLは、LEFTをRIGHTに書き換えるだけです。
SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
部署マスタ.所属部署, 部署マスタ.部署名称
FROM 社員一覧
RIGHT OUTER JOIN 部署マスタ
ON 社員一覧.所属部署 = 部署マスタ.所属部署;
このように「部署マスタ」のレコードは全て抽出対象となり、取得できなかった「人事課」に対応する「社員番号」「氏名」「等級」の空欄は、全てNULLで埋めた結果が出力されました。
■FULL OUTER JOINの場合
FULL OUTER JOINでテーブルを抽出するSQLは、こちらもLEFTをFULLに書き換えるだけです。
SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
部署マスタ.所属部署, 部署マスタ.部署名称
FROM 社員一覧
FULL OUTER JOIN 部署マスタ
ON 社員一覧.所属部署 = 部署マスタ.所属部署;
このようにFULL OUTER JOINでは、「社員一覧」「部署マスタ」のレコードは全て抽出対象となります。取得できなかった項目には、LEFTやRIGHT同様にNULLで埋められた状態で出力されました。
4.結局、内部結合と外部結合の違いとは?
これらの説明からお察しであると思いますが、内部結合と外部結合の違いをまとめると次のようになります。
・内部結合は、一致するレコードのみ抽出する
・外部結合は、一致しないレコードも抽出する
業務でSQLを組んでいると、内部結合や外部結合の使い分けは必須になります。この機会にぜひ覚えておいてみて下さいね。
関連記事:
無料で今日からDB導入!データベース作成に関するフリーソフトまとめ
関連記事:
リレーショナルデータベース正規形の種類と正規化手順
関連記事:
かけだしSEのためのデータベース設計入門