シンプルにSQLの内部結合と外部結合の違いを理解する
はじめに
SQLの内部結合と外部結合の違いって、曖昧のままでも結構何とかなってしまうと思います。
ただ、しっかり理解しないままクエリを作成すると、後々「データが取得できてない。。」みたいな事が起こってしまいます。
特に業務システムでは、ExcelやPDFで帳票ファイルを出力する処理で意図したデータが出力されないことは、かなり問題となります。
そこで、本記事では内部結合と外部結合の違いについて整理をしてみました。
テーブル結合の文法や他の結合方式については割愛し、シンプルに内部結合と外部結合の違いをまとめました。
テーブル結合の方法は一つではない
これが原因で、テーブル結合の苦手意識が生まれている気がします。
同じJOIN句でもLEFTがある場合と無い場合があって、「前に解析したクエリと何が違うんだ?」となってしまいがちです。
ここでは顧客の注文状況を管理するシステムを例に、二つの結合の違いを見ていきます。
顧客データは顧客テーブルに、顧客の注文情報はcustomer_idを外部キーとして注文テーブルに保存します。
顧客テーブル(customers)
| customer_id | name |
|---|---|
| 1 | 佐藤 |
| 2 | 鈴木 |
| 3 | 高橋 |
注文テーブル(orders)
| order_id | customer_id | product |
|---|---|---|
| 101 | 1 | パソコン |
| 102 | 1 | マウス |
| 103 | 2 | キーボード |
内部結合でも外部結合でも、ここでのテーブル結合の目的は、顧客情報を注文状況と合わせて取得することです。
それでは二つの結合の違いを見ていきましょう。
内部結合(INNER JOIN)
内部結合を用いたクエリは以下のように記述できます。
SELECT c.customer_id, c.name, o.order_id, o.product
FROM customers c
INNER JOIN orders o
ON c.customer_id = o.customer_id;
実行結果:
| customer_id | name | order_id | product |
|---|---|---|---|
| 1 | 佐藤 | 101 | パソコン |
| 1 | 佐藤 | 102 | マウス |
| 2 | 鈴木 | 103 | キーボード |
内部結合の特徴は、2つのテーブルの両方に存在している情報だけを取得する点です。
そのため、注文テーブルにcustomer_idが無い、customer_id = 3の高橋さんは取得されません。
外部結合(OUTER JOIN)
次に外部結合です。
外部結合を用いたクエリは以下のように記述できます。
SELECT c.customer_id, c.name, o.order_id, o.product
FROM customers c
LEFT JOIN orders o
ON c.customer_id = o.customer_id;
実行結果:
| customer_id | name | order_id | product |
|---|---|---|---|
| 1 | 佐藤 | 101 | パソコン |
| 1 | 佐藤 | 102 | マウス |
| 2 | 鈴木 | 103 | キーボード |
| 3 | 高橋 | NULL | NULL |
内部結合の取得結果と比べると、高橋さんのレコードが取得されていることが大きな違いです。
このように外部結合の特徴は、どちらか一方のテーブルの情報はすべて取得される点にあります。
もう1つの外部結合の特徴は、テーブルの情報を全て取得する側のテーブル(ここではマスタと称します)を、キーワードを用いて指定する必要があるという点です。
キーワードは以下で指定します。
-
LEFT:FROM句で左側に書いたテーブルをマスタに指定する -
RIGHT:FROM句で右側に書いたテーブルをマスタに指定する -
FULL:両方のテーブルに存在する行に加え、どちらか一方にのみ存在する行もすべて残す(本記事では詳細は割愛)
試しに、RIGHT JOINで実行した場合の結果を確認してみましょう
SELECT c.customer_id, c.name, o.order_id, o.product
FROM customers c
RIGHT JOIN orders o
ON c.customer_id = o.customer_id;
実行結果:
| customer_id | name | order_id | product |
|---|---|---|---|
| 1 | 佐藤 | 101 | パソコン |
| 1 | 佐藤 | 102 | マウス |
| 2 | 鈴木 | 103 | キーボード |
もし注文テーブル内に存在しない顧客がいた場合は、customers側(customer_id、name)がNULLになりますが、今回のデータではすべての注文が顧客に結びついているため、INNER JOINと同じ結果になっています。
どう使いわけるか
2つの結合の違いが分かると、目的によって結合の種類を使い分ける事ができます。
例えば、全ての顧客データをもとに、各顧客がどの位商品を購入したかを集計したいとします。
この場合は、一度も注文してない顧客も除外せず、全顧客のデータがほしいので、外部結合を選択します。
業務システムで帳票を作成する場合は、データの全体像が見えなくなることを防ぐために、外部結合を利用している場合が多い気がします。
図でイメージしよう
webで調べてみると、テーブル結合を図を用いて解説している記事を見つけました。
この図を知っているだけで、各結合がどこからデータを取得しているかがイメージできるようになりますね。

引用)https://red9.com/blog/sql-joins-venn-diagram/
まとめ
内部結合:2つのテーブルの両方に存在している情報だけを選択する
外部結合:どちらか一方のテーブルの情報はすべて取得される、マスタをLEFT,RIGHTキーワードで指定する
2つの結合の違いは、一度理解すればそれ程難しいものではなく、使いこなせると思います。
本記事がSQLの理解の一助となれば幸いです。
Discussion