SQL初心者の方が躓きやすいポイントとして、テーブル結合における内部結合(INNER JOIN)と外部結合(OUTER JOIN)の違いが挙げられます。
今回はSQL初心者の方に、内部結合と外部結合の違いを理解してもらえるよう、サンプルコードを掲載しながら解説していきたいと思います。
SQLの内部結合と外部結合の違いを把握しよう
まずSQLのテーブル結合に関してですが、2つ以上のテーブルからデータを抽出する際に利用します。
テーブル結合には大きく2つの方法が存在し、「内部結合(INNER JOIN)」と「外部結合(OUTER JOIN)」と呼ばれます。
内部結合
まず内部結合についてご紹介してきます。
内部結合は指定した結合条件に一致するデータが双方のテーブルから取得される記述方法です。
SELECT (テーブル名.)カラム名(, ....) FROM テーブル1 INNER JOIN テーブル2 ON テーブル2.カラム名 = テーブル1.カラム名 (INNER JOIN テーブル3 ON テーブル3.カラム名 = テーブル1(2).カラム名)
SELECTにはカラム名を指定せず「*」を指定すると結合した双方全てのカラムのデータを取得して表示します。
外部結合
次に外部結合(LEFT OUTER JOIN)についてご紹介します。
外部結合は結合条件に一致するしないに関わらず軸となるテーブルのデータを全て取得します。
一方で、結合するテーブルに関しては結合条件に一致するデータのみが抽出されます。
SELECT (テーブル名.)カラム名(, ....) FROM テーブル1 LEFT (OUTER) JOIN テーブル2 ON テーブル2.カラム名 = テーブル1.カラム名 (LEFT JOIN テーブル3 ON テーブル3.カラム名 = テーブル1(2).カラム名)
上記説明の場合、軸となるテーブルがテーブル1のため、テーブル1のデータは全て選択対象となります。
一方で結合先のテーブル2に関してはON句で指定した条件式に一致するデータのみが表示されます。
テーブル2のデータが取得出来なかったカラムには全てNULLが設定されます。
SQLで内部結合と外部結合をそれぞれ実行してみよう
実際にサンプルコードでSQLの内部結合と外部結合を実行して違いを確認してみましょう。
今回は下記の3つのテーブルを利用します。
userテーブル
+------+--------------+------+ | id | name | age | +------+--------------+------+ | 1 | 山田花子 | 22 | | 2 | 山田太郎 | 33 | | 3 | 佐藤一郎 | 44 | +------+--------------+------+
productテーブル
+------+-----------------------+--------+ | id | name | price | +------+-----------------------+--------+ | 1 | ノートパソコン | 100000 | | 2 | スマートフォン | 50000 | | 3 | タブレット | 70000 | +------+-----------------------+--------+
purchaseテーブル
+------+---------------------+---------+------------+ | id | pur_date | user_id | product_id | +------+---------------------+---------+------------+ | 1 | 2020-01-01 12:00:02 | 2 | 3 | | 2 | 2020-01-03 14:00:00 | 1 | 4 | | 3 | 2020-01-03 16:00:00 | 2 | 1 | +------+---------------------+---------+------------+
内部結合のサンプル
ではまず内部結合のサンプルをご紹介します。
「user」テーブルと「purchase」テーブルをユーザーのidで紐付けます。
SELECT * FROM user INNER JOIN purchase ON purchase.user_id = user.id;
実行した結果が下記の通りです。
+------+--------------+------+------+---------------------+---------+------------+ | id | name | age | id | pur_date | user_id | product_id | +------+--------------+------+------+---------------------+---------+------------+ | 2 | 山田太郎 | 33 | 1 | 2020-01-01 12:00:02 | 2 | 3 | | 1 | 山田花子 | 22 | 2 | 2020-01-03 14:00:00 | 1 | 4 | | 2 | 山田太郎 | 33 | 3 | 2020-01-03 16:00:00 | 2 | 1 | +------+--------------+------+------+---------------------+---------+------------+
purchaseテーブルにデータの存在しない、userテーブルのid=3のデータは取得出来ていないことをご確認頂けます。
外部結合のサンプル
では次に、上記SQLの内部結合を外部結合に変更すると取得結果がどのように変わるのか確認していきたいと思います。
SELECT * FROM user LEFT JOIN purchase ON purchase.user_id = user.id;
実行した結果が下記の通りです。
+------+--------------+------+------+---------------------+---------+------------+ | id | name | age | id | pur_date | user_id | product_id | +------+--------------+------+------+---------------------+---------+------------+ | 2 | 山田太郎 | 33 | 1 | 2020-01-01 12:00:02 | 2 | 3 | | 1 | 山田花子 | 22 | 2 | 2020-01-03 14:00:00 | 1 | 4 | | 2 | 山田太郎 | 33 | 3 | 2020-01-03 16:00:00 | 2 | 1 | | 3 | 佐藤一郎 | 44 | NULL | NULL | NULL | NULL | +------+--------------+------+------+---------------------+---------+------------+
内部結合では取得出来ていなかったuserテーブルのid=3のデータが取得されています。
これは外部結合が軸となるテーブル(今回の場合user)のデータを全て取得した上で、結合条件に一致するデータを結合先のテーブルから取得するためです。
purchaseテーブルにuser_id=3のデータは存在しないため、全てNULLが設定されていることも合わせて確認しておいてください。
組み合わせて利用することももちろん可能
内部結合と外部結合のSQLは組み合わせて利用することももちろん可能です。
userテーブルとpurchaseテーブルを内部結合した上で、productテーブルを外部結合するSQLを組んでみたいと思います。
取得カラムが多くなるため、特定カラムのみに絞って表示しています。
SELECT user.id, user.name, purchase.id, purchase.pur_date, product.id, product.name FROM user INNER JOIN purchase ON purchase.user_id = user.id LEFT JOIN product ON product.id = purchase.product_id;
実行した結果が下記の通りです。
+------+--------------+------+---------------------+------+-----------------------+ | id | name | id | pur_date | id | name | +------+--------------+------+---------------------+------+-----------------------+ | 2 | 山田太郎 | 3 | 2020-01-03 16:00:00 | 1 | ノートパソコン | | 2 | 山田太郎 | 1 | 2020-01-01 12:00:02 | 3 | タブレット | | 1 | 山田花子 | 2 | 2020-01-03 14:00:00 | NULL | NULL | +------+--------------+------+---------------------+------+-----------------------+
上記サンプルでは、購入履歴のないユーザー(user.id=3)のデータは取得出来ていませんが、商品テーブルにデータがなくなってしまっている(product.id=4)の購入履歴情報は、NULLを設定した状態で取得出来ていることがご確認頂けます。
さいごに:SQLでは内部結合と外部結合で取得出来るデータは大きく異なる
本記事では、SQLにおける内部結合と外部結合の違いについてご紹介してきました。
内部結合と外部結合は記述方法自体はほとんど同じですが、取得出来るデータに大きな差が生まれます。
どちらのテーブル結合を使うべきかを理解するためには、仕様をきちんと把握することが大切です。
外部結合にはLEFT OUTER JOINとRIGHT OUTER JOINと呼ばれる2種類の方法が存在しますが、本記事では一般的に利用されるLEFT OUTER JOINで内部結合との違いを解説していきます。