この記事では、弊社の新人エンジニア研修の参考にMySQLを解説します。
前回は、検索結果のソート、グループ化と集約関数を解説しました。
今回は、複数テーブルに対する検索について解説します。
1. テーブル結合の必要性
これまでは単一のテーブルに対してのみの操作でした。しかし、リレーショナルデータベースは正規化の考え方に則り、複数テーブルに分けてデータを格納することが一般的です。複数のテーブルにまたがったデータを使って結合できなければせっかくのデータベースの機能を活用することはできません。そこで複数のテーブルを結合する操作が重要になります。この操作はリレーショナル・データベースの3種類の表操作のうち結合【join】にあたります。
joinにはさまざまな種類があることが「SQL JOIN Diagram」でグーグル検索すればお分かりになると思います。そのうち、今回は内部結合と左外部結合の2つを紹介します。
2. 内部結合
内部結合とは、結合条件に指定している値が両方のテーブルに存在するレコードを抽出する結合方法です。結合条件に指定している値が一方のテーブルにのみ存在するレコードは抽出されません。
【内部結合の例】
なお、結合の前提として一方のテーブルの主キーが他方のテーブルの外部キーとして組み込まれている必要があります。そうでないと、レコードとレコードを結合する手がかりが無くなってしまうからです。(下記 表名1.列名 = 表名2.列名 の部分)
※標準SQLではINNER JOINと書きます。INNERが省略できるのはMySQL特有の文法です。
※もしも、フィールド名だけで表名が特定できる場合は、単にフィールド名だけを書けばよく、 表名1.列名 のように書く必要はありません。
ちなみに英語の【join】は結合するという意味があります。また、英語の【on】は基本的には何かに接しているという意味の接続詞ですが、日本語同様、「~の上で」のような条件を示す際にもよく使われます。例えば、【on the condition that】には「~という条件で」という意味があります。
以下の7_1.sqlはcars表とsales表を結合して、car_id,name,saleDatetTimeを抽出するSQL文です。
SELECT
cars.car_id, name, saleDateTime
FROM
cars
JOIN
sales ON cars.car_id = sales.car_id;
<結果の例>
なお、表名を付けずにフィールド名だけで実行しようとすると「Column 'カラム名' in field list is ambiguous」というエラーメッセージが表示されますので試しておいてください。【 ambiguous 】=曖昧だとの指摘ですね。どの表の列であるかを明示するために「表名.フィールド名」のように指定することを忘れないようにしましょう。
慣れないうちは以下7_2.sqlのようにフィールド名に「*」を使い、まずはテーブルの結合を優先させ、全てのテーブルが結合された大きなテーブルを得ます。その後で結合済みのテーブルを見ながらゆっくりと対象の列を選択するのが良いでしょう。(下図参照)
SELECT
*
FROM
cars
JOIN
sales ON cars.car_id = sales.car_id;
<結果の例>
この方法はテーブルが3つ以上に増えてきた場合にも威力を発揮します。
なお、ASを使って別名をつけると複雑な条件もシンプルに書くことができます。
SELECT
ca.car_id, ca.name, price, cs.name, saleDateTime
FROM
cars AS ca
JOIN
sales AS s ON ca.car_id = s.car_id
JOIN
customers AS cs ON s.customer_id = cs.customer_id;
3. 左外部結合
外部結合とは、 結合条件に指定している値がテーブルのどちらか一方にしかないレコードも抽出することができる結合方法です。
【左外部結合の例】
ここで左側のテーブルと呼んでいるのは、以下のSQLの構文の表1にあたる先に記述する方のテーブルです。
※MySQLの場合、 OUTERは省略可
以下の7_7.sqlはcars表とsales表を左外部結合してcar_id, name, saleDateTimeを表示します。cars表を“左”に置きますので1台も売れていない車も表示されます。
※この演習をする際にはsales表からsale_idが5以上のデータを削除してから試してください。
SELECT
c.car_id, name, saleDateTime
FROM
cars AS c
LEFT JOIN
sales AS s ON c.car_id = s.car_id;
<結果の例>
右外部結合もありますが、左右を入れ替えれば同じことですからここでは解説を割愛します。
以上、複数テーブルに対する検索について見てきました。
完全外部結合というのもあるのですが、MySQLでは直接指定できないためこの記事では省略しています。
興味のある方はインターネットで調べてみてください。
次回はSQLの中にSQLを書く副問合せについて見ていきましょう。
IT企業向け新人研修おすすめ資料 無料公開中 (saycon.co.jp)