データベースを学習する際、一番最初に学習することになる「テーブル結合」ですが、「INNER JOIN」「LEFT JOIN」「LEFT OUTER JOIN」といった結合方法があり、どんな時にどの結合方法を使えばよいのか分かりにくいですよね。
特に、外部結合によるデータ抽出をする際、条件をONに書くかWHERE句に書くかを正確に把握していなければ、誤った抽出結果となってしまい、システム障害を引き起こしかねません。
今回はデータベース初心者を対象に、リレーションデータベースでのテーブル結合の説明や注意点をまとめ、どのようなSQLを記述すればよいのかを紹介したいと思います。
目次
テーブル結合とは
「テーブル結合」とはデータを抽出する際に用いる手法です。
MySQLに限らず、AccessやOracleといったデータベースからデータを抽出する際に使用しますが、結合方法が変わるだけで抽出される結果も異なってくるため「テーブル結合」に関する知識を整理しておくことはとても重要です。
まずは、どういったデータベースで「テーブル結合」が用いられるのか、といった内容から見ていきましょう。
データベース
データベースはおもに「階層型データベース」「ネットワーク型データベース」「リレーショナル型データベース」の3つに分類されていますが、その中で、「テーブル結合」の手法が用いられるのは「リレーショナル型データベース」となります。
例えば、ある企業の社員表を「社員ID」「名前」「役職」「所属先」といった項目で管理している場合、リレーショナルデータベースでは、「社員」という表(テーブル)と「役職」という表(テーブル)、「所属先」という表(テーブル)といった具合に、複数のテーブルに分けてデータを管理することになるため、データを抽出する際にそれらをつなげるための「テーブル結合」を行う必要が発生します。
具体的には以下のような項目を持つテーブルの中から対象となる項目を指定し、それぞれの項目の値が一致しているかどうか等の判定をしてデータを抽出していくことになるのですが、抽出したい内容によって「内部結合」や「外部結合」といった結合を使い分けていくことになります。
「社員」テーブル 「社員ID」「名前」「役職コード」「所属先コード」 |
「役職」テーブル 「役職コード」「役職名」 |
「所属先」テーブル 「所属先コード」「所属先名」 |
それでは、「内部結合」「外部結合」について解説していきたいと思います。
内部結合
例えば、以下のようなデータが登録されているデータベースから社員の「名前」と「所属先」の一覧を作成するには「社員」と「所属先」の両方のテーブルにある「所属先コード」という項目を指定して結合させることになります。
社員テーブル
社員ID | 名前 | 役職コード | 所属先コード |
---|---|---|---|
1 | 田中 | 1 | A |
2 | 鈴木 | 2 | B |
3 | 山田 | 3 | A |
4 | 佐藤 | 4 | A |
5 | 高橋 | 4 | B |
6 | 山中 |
役職
役職コード | 役職名 |
---|---|
1 | 社長 |
2 | 支店長 |
3 | 専務 |
4 | 一般 |
所属先
所属先コード | 所属先名 |
---|---|
A | 本社 |
B | 東京支店 |
C | 大阪支店 |
「所属先コード」で社員テーブルと所属先テーブルを結合
名前 | 所属先コード | 所属先名 |
---|---|---|
田中 | A | 本社 |
鈴木 | B | 東京支店 |
山田 | A | 本社 |
佐藤 | A | 本社 |
高橋 | B | 東京支店 |
このように、2つのテーブルで結合の対象となる項目を指定し、それぞれの項目に同じ値が格納されているデータを取得する結合方法を「内部結合」と呼んでいます。
内部結合では2つのテーブルの項目に同じ値が格納されているデータを結合することになりますが、一致しない場合はデータを取得しないという特徴があります。
外部結合
「内部結合」で社員テーブルと所属先テーブルを結合させた場合、所属先が決まっていない社員ID:6の山中さんが出力されていないことにお気づきでしょうか。
内部結合の特徴は上述の通りですので、「所属先コード」が空白の山中さんは「所属先」テーブルと一致するデータがないため、データを取得されません。
山中さんを出力させたい場合は、「2つのテーブルの項目に同じ値が格納されている場合に結合してデータを取得し、一致しない場合はそのまま出力する」という条件でデータを取得する必要があります。
なお、この条件でテーブルを結合する方法が「外部結合」と呼ばれています。データベースからデータを抽出する場合、「内部結合」か「外部結合」をつかってデータを抽出していくことになりますので、2つの用語はしっかりと把握しておきましょう。
リレーションシップ
余談ですが、「テーブル結合」の意味を学ぶ際に、「リレーションシップ」という用語と比較しておきましょう。
「リレーションシップ」という用語については、用いられる場面によって意味合いが異なり、データベースの世界で用いられる場合には「複数の表の集まり」という意味で用いられたり、「E-R図」などのデータベースを設計する際に用いられる場合は「表同士をつなげる関係性」という意味で用いられたりしています。
どちらも「複数のテーブルをくっつける」といった感覚で用いられることが多いので、よく混同されがちなのですが、「テーブル結合」と「リレーションシップ」は全く異なるものである、という点だけは覚えておいていただければと思います。
JOIN句を含むSQLも楽に扱える!PHPからMySQLを効率よく使う方法JOINを使った結合
それでは、内部結合や外部結合を指定する場合、実際のSQLでどのように記述すればよいか見ていきましょう。
JOIN(内部結合)
内部結合の場合は「JOIN」と記述します。
前述の例の場合、以下のように記述します。
1 2 3 4 5 |
SELECT 名前,所属先コード,所属先名 FROM 社員 JOIN 所属先 ON 社員.所属先コード = 所属先.所属先コード |
出力結果
名前 | 所属先コード | 所属先名 |
---|---|---|
田中 | A | 本社 |
鈴木 | B | 東京支店 |
山田 | A | 本社 |
佐藤 | A | 本社 |
高橋 | B | 東京支店 |
ポイントはSQLのFROM句でテーブル同士を「JOIN」でつなぎ、その後に「ON」で結合する条件を記述する点。
内部結合であることを明示的にしたい場合は、「JOIN」ではなく「INNER JOIN」と記述している場合もありますが、「JOIN」と記述されていれば「内部結合」を表しますので、状況に応じて使い分けれられるようになっておくとよいでしょう。
OUTER JOIN(外部結合)
外部結合の場合は「OUTER JOIN」と記述します。
ただし、FROM句で2つのテーブルをつなげる際、左右のどちらのテーブルのデータを基準に出力させたいのかを指定する必要があります。
FROM句に記述する左側の「社員」テーブルを基準にする場合、以下のように記述します。
1 2 3 4 5 |
SELECT 名前,所属先コード,所属先名 FROM 社員 LEFT OUTER JOIN 所属先 ON 社員.所属先コード = 所属先.所属先コード |
出力結果
名前 | 所属先コード | 所属先名 |
---|---|---|
田中 | A | 本社 |
鈴木 | B | 東京支店 |
山田 | A | 本社 |
佐藤 | A | 本社 |
高橋 | B | 東京支店 |
山中 |
LEFT JOIN
外部結合の場合、「OUTER」を省略することができます。
「LEFT JOIN」と記述しても「LEFT OUTER JOIN」の外部結合を表しますので、こちらも状況に応じて使い分けられるようになっておくとよいでしょう。
RIGHT JOIN
右側の「所属先」テーブルを基準に外部結合する場合は以下の通りです。
1 2 3 4 5 |
SELECT 名前,所属先コード,所属先名 FROM 社員 RIGHT JOIN 所属先 ON 社員.所属先コード = 所属先.所属先コード |
出力結果
名前 | 所属先コード | 所属先名 |
---|---|---|
田中 | A | 本社 |
鈴木 | B | 東京支店 |
山田 | A | 本社 |
佐藤 | A | 本社 |
高橋 | B | 東京支店 |
大阪支店 |
FROM句(ON)・WHERE句での条件
SQLに内部結合、外部結合を指定するだけであれば、上述の内容の説明だけで問題ないのですが、SQLのやっかいなところは、ONに検索条件を記述したり、Where句に結合条件を記述したりする場合もある、といったところでしょう。
実際の業務ではWhere句で結合条件を記述している例も少なくはないため、知識として知っていなければ「結合条件がない」と誤解してしまう可能性もありますので、いくつか事例を見てみましょう。
Where句に結合条件
WHERE句に結合条件を記述している場合は以下のような記述です。
1 2 3 4 5 |
SELECT 名前,所属先コード,所属先名 FROM 社員 JOIN 所属先 WHERE 社員.所属先コード = 所属先.所属先コード |
出力結果
名前 | 所属先コード | 所属先名 |
---|---|---|
田中 | A | 本社 |
鈴木 | B | 東京支店 |
山田 | A | 本社 |
佐藤 | A | 本社 |
高橋 | B | 東京支店 |
内部結合の場合、WHERE句に結合条件を記述することは問題ありません。
この場合、ONに結合条件を記述した場合と同じ結果がかえってきますので、WHERE句でも結合条件を指定することができる点について覚えておくとよいでしょう。
ですが、外部結合の場合、WHERE句に結合条件を記述することはできません。
以下のようなSQLはエラーとなってしまいますので注意してください。
1 2 3 4 5 |
SELECT 名前,所属先コード,所属先名 FROM 社員 LEFT JOIN 所属先 WHERE 社員.所属先コード = 所属先.所属先コード |
ONでの絞り込み
基本的にはONに結合条件を記述するのが望ましいのですが、ONに検索条件を記述する場合もあります。
例えば、社員全員のリストから「役職」が「一般」以外の社員の役職名を表示させたい場合などは以下のようなSQLとなります。
1 2 3 4 5 6 7 |
SELECT 名前,役職コード,役職名 FROM 社員 LEFT JOIN 役職 ON 社員.役職コード = 役職.役職コード AND 役職.役職コード <> ‘一般’ |
このようなSQLの場合、役職が「一般」の場合は空欄で表示し、「一般」以外の役職のみ表示されます。
出力結果
名前 | 役職コード | 役職名 |
---|---|---|
田中 | 1 | 社長 |
鈴木 | 2 | 支店長 |
山田 | 3 | 専務 |
佐藤 | ||
高橋 |
どのようなリストを作りたいのかで自在に使い分けられるようになっておくとよいでしょう。
Where句での条件指定
最後に、以下のようなSQLで記述した場合、どのような出力となるか試しておきましょう。
1 2 3 4 5 6 7 |
SELECT 名前,役職コード,役職名 FROM 社員 LEFT JOIN 役職 ON 社員.役職コード = 役職.役職コード WHERE 役職.役職コード <> ‘一般’ |
出力結果
名前 | 役職コード | 役職名 |
---|---|---|
田中 | 1 | 社長 |
鈴木 | 2 | 支店長 |
山田 | 3 | 専務 |
ONで条件指定した場合とWHEREで条件指定した場合の違いが確認できるかと思います。
まとめ
いかがでしたか。
データベースにおけるテーブル結合方法が把握できましたでしょうか。
テーブル結合を理解しておかなければ正しいデータ抽出が行えないだけでなく、いずれ学習していくことになる「正規化」や「ER図」などへの理解もおぼつかなくなってしまいます。
テーブルの結合方法はリレーショナルデータベースの基礎とも言える内容ですので、今後、「テーブルの結合」の知識を再確認したい時がありましたら、こちらの記事を思い出していただけると幸いです。
【PHP入門】MySQLの基本を解説!