【SQL】テーブル結合の全パターンを総まとめ!初心者向けに解説

SQLでSELECT文を書いていると、複数のテーブルをがっちゃんこしたい!と思う時があるでしょう。これをSQLではテーブル結合と言います。

テーブル結合ができるようになれば、分析の幅が大きく広がります。むしろ、テーブル結合なしには分析ができないと言っても過言ではないくらい重要です。

本記事ではテーブル結合とは何か?から始まり、結合の種類や使い方について詳しく解説しています。

SQLのテーブル結合とは

SQLのテーブル結合とは、文字通り複数のテーブルを結合することを指します。

これだけではイメージが付きにくいので図解を交えて解説します。

例えば、ユーザー情報を管理するusersテーブルと、注文情報を管理するorderテーブルが存在したとします。

ここからユーザーが注文した商品を集計したい時どうすればいいでしょう。

1つ考えられるやり方として、usersテーブルとorderテーブルの情報をそれぞれ抽出して、エクセルにインポートして照合する方法です。

しかし、毎回これをするのは面倒ですし何よりも時間がかかります。

できることならSQL上で統合を行なって分析を行いたいものです。これを実現するのが「SQLのテーブル結合」です。

テーブル結合を使えばエクセルで行っていた統合作業をSQL上で行うことができます。

usersテーブルのIDorderテーブルのuser_idは一致するため、この2つを起点としてテーブルを結合することができます。

今回はid情報を元に結合を行いましたが、複数のテーブルで同じ値を扱うカラムが存在すればid以外でもテーブル結合は可能です。

例えば、テーブルAとテーブルBのどちらにもemailの情報が存在していれば、emailを起点としてテーブル結合をするといった具合です。

SQLで使える結合は5種類

テーブル結合とは何かを説明してきましたが、実は結合の種類は一つではありません。

下記の5種類が存在します。

結合の種類イメージ図概要
1. 内部結合
(INNER JOIN)
値が一致したレコードだけを結合
2. 外部結合
(LEFT OUTER JOIN)
左(A)の全てのレコードを取得
+
左(A)と値が一致した右(B)のレコードを結合
3. 外部結合
(RIGHT OUTER JOIN)
右(B)の全てのレコードを取得
+
右(B)と一致した左(A)のレコードを結合
4. 外部結合
(FULL OUTER JOIN)
左(A)と右(B)の全てのレコードを取得
5. クロス結合
(CROSS JOIN)
テーブルの全ての組み合わせを取得

それでは、具体例を交えて一つずつ解説していきます。

サンプルデータ

下記のとおり、employeeテーブルとdepartmentテーブルを用意します。

employeeテーブルは従業員情報を管理し、departmentテーブルは配属部門を管理しています。

employeeテーブル

idnamedepartment_id
1山田3
2鈴木4
3佐藤1
4佐々木6
5丸山1
employeeテーブル

departmentテーブル

idname
1営業部
2人事部
3企画部
4経理部
5開発部
departmentテーブル

SQLの内部結合「INNER JOIN」

内部結合は、それぞれのテーブルで指定した値が一致したレコードだけを結合します。実務で最も使うのがINNER JOINを使った内部結合なので、必ず押さえておきましょう。

INNER(内部)というだけあって、
テーブルAとテーブルBの一致したレコードのみを取得

今回の場合、employeeテーブルのdepartment_idとdepartmentテーブルのidが同じ意味を持つカラムになっているため、この2つを起点として結合を行います。

結果、department_ididカラムそれぞれの値が一致したレコードだけが結合されます。これが内部結合INNER JOINです。

INNER JOINの基本構文が下記です。

SQL
SELECT カラム名
FROM テーブル名1
INNER JOIN テーブル名2
ON 結合の条件;

INNER JOINの後に結合するテーブル名を記載し、ONの後にテーブル名1テーブル名2を結合するための条件を記載します。

検索クエリ

employeeテーブルとdepartmentテーブルを内部結合して取得する

SQL
SELECT *
FROM employee
INNER JOIN department
ON employee.department_id = department.id;

考え方は下記です。

  1. SELECT文でemployeeテーブルから全ての情報を取得する命令を出す
  2. INNER JOINでdepartmentテーブルをemployeeテーブルに結合する命令を出す
  3. ONの後にemployee.department_id = department.idと書くことで、employeeテーブルとdepartmentテーブルを結合するための条件を指定

実行結果

idnamedepartment_ididname
3佐藤11営業部
1山田33企画部
2鈴木44経理部
5丸山11営業部

department_ididが結合された上でレコードを取得することができました。両方のカラムに存在する値だけが残っていることが分かります。

また、テーブルを結合すると同じ名前のカラムが複数できるので、AS句を使って別名をつけると分かりやすくなります。

内部結合INNER JOINについては下記でも詳しくまとめています。

【SQL】INNER JOINを使ってテーブルを結合する方法

SQLの外部結合「OUTER JOIN」

外部結合は、内部結合のように2つのテーブルで指定したカラムの値が一致するレコードに加えて、どちらかのテーブルにしか存在しないレコードも取得します。

そして、外部結合には下記の3種類が存在します。

  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN

それぞれ順に見ていきましょう。

LEFT OUTER JOIN

左側のテーブル全て
+
テーブルAとテーブルBの一致したレコード

今回の場合、テーブルAをemployeeテーブルとすると、department_idが結合の起点になります。

下記の図のようにdepartment_idのレコードは全て取得した上で、テーブルBのdepartmentテーブルのidが一致するレコードを取得します。

そしてポイントが、結合先であるdepartmentテーブルに存在しない値がある場合にはNULLが割り当てられるということです。department_idが6に一致する値はdepartmentテーブルには存在しないためNULLとなっています。

あくまで左側のテーブルが起点となるのが左外部結合のLEFT OUTER JOINです。

LEFT OUTER JOINの基本構文が下記です。

SQL
SELECT カラム名
FROM テーブル名1
LEFT OUTER JOIN テーブル名2
ON 結合の条件;

テーブル名1に結合元(起点)となるテーブルを指定し、テーブル名2に結合先のテーブルを指定します。

検索クエリ

employeeテーブルにdepartmentテーブルを左外部結合(LEFT OUTER JOIN)して取得する

SQL
SELECT *
FROM employee
LEFT OUTER JOIN department
ON employee.department_id = department.id;

考え方は下記です。

  1. SELECT文でemployeeテーブルから全ての情報を取得する命令を出す
  2. LEFT OUTER JOINでemployeeテーブルを起点として、departmentテーブルを結合する命令を出す
  3. ONの後にemployee.department_id = department.idと書くことで、employeeテーブルとdepartmentテーブルを結合するための条件を指定

また、LEFT OUTER JOINLEFT JOINと省略して書くことも可能です。

実行結果

idnamedepartment_ididname
3佐藤11営業部
1山田33企画部
2鈴木44経理部
4佐々木6NULLNULL
5丸山11営業部

employeeテーブルを起点としてdepartmentテーブルを結合することができました。departmentテーブルはid6の値は存在しないため、代わりにNULLが割り当てられています。

LEFT OUTER JOINについては下記の記事でも詳しくまとめています。

【SQL】LEFT OUTER JOINを使って外部結合をする方法

RIGHT OUTER JOIN

右側のテーブル全て
+
テーブルAとテーブルBの一致したレコード

RIGHT OUTER JOINLEFT OUTER JOINの真逆と覚えておけばOKです。右側のテーブルに対して左側のテーブルを結合します。今回の場合は、departmentテーブルに対してemployeeテーブルを結合することになります。

下記の図のようにdepartmentテーブルのidは全て取得した上で、employeeテーブルのdepartment_idが一致するレコードを取得します。

結合元のdepartmentテーブルのidに存在して、結合先であるemployeeテーブルのdepartment_idに存在しない値があれば、NULLが割り当てられます。

あくまで右側のテーブルが起点となるのが右外部結合のRIGHT OUTER JOINです。

RIGHT OUTER JOINの基本構文が下記です。

SQL
SELECT カラム名
FROM テーブル名1
RIGHT OUTER JOIN テーブル名2
ON 結合の条件;

検索クエリ

employeeテーブルにdepartmentテーブルを右外部結合(RIGHT OUTER JOIN)して取得する

SQL
SELECT *
FROM employee
RIGHT OUTER JOIN department
ON employee.department_id = department.id;

また、RIGHT OUTER JOINRIGHT JOINと省略して書くことも可能です。

実行結果

idnamedepartment_ididname
1山田33企画部
2鈴木44経理部
3佐藤11営業部
5丸山11営業部
NULLNULLNULL2人事部
NULLNULLNULL5開発部

departmentテーブルを起点にしてemployeeテーブルを結合することができました。

departmentテーブルのid25の値はemployeeテーブルは存在しないため、NULLが保存されています。

FULL OUTER JOIN

テーブルAとテーブルBの全て

FULL OUTER JOINは両者総取りです。

下記3点に該当するレコードを取得します。

  • テーブルAとテーブルBのカラムの値が一致するレコード
  • テーブルAには存在して、テーブルBのカラムには値が存在しないレコード
  • テーブルAには存在せず、テーブルBのカラムには値が存在するレコード

どちらか一つのテーブルにしか存在しない値がある場合は、もう一方のカラムにはNULLが保存されます。

FULL OUTER JOINはMySQLなど一部のデータベースでは対応していないためご注意ください。

FULL OUTER JOINの基本構文は下記です。

SQL
SELECT カラム名
FROM テーブル名1
FULL OUTER JOIN テーブル名2
ON 結合の条件;

検索クエリ

employeeテーブルにdepartmentテーブルを完全外部結合(FULL OUTER JOIN)して取得する

SQL
SELECT *
FROM employee
FULL OUTER JOIN department
ON employee.department_id = department.id;

また、FULL OUTER JOINFULL JOINと省略して書くことも可能です。

実行結果

idnamedepartment_ididname
1山田33企画部
2鈴木44経理部
3佐藤11営業部
4佐々木6NULLNULL
5丸山11営業部
NULLNULLNULL2人事部
NULLNULLNULL5開発部

employeeテーブルとdepartmentテーブルを完全外部結合することができました。

employeeテーブルのdepartment_id6の値はdepartmentテーブルには存在しないためNULLが保存されています。一方で、departmentテーブルのid25の値はemployeeテーブルには存在しないため、NULLが保存されています。

このように、LEFT OUTER JOINRIGHT OUTER JOINを足し合わせたものがFULL OUTER JOINと覚えておきましょう。

SQLのクロス結合「CROSS JOIN」

最後に、クロス結合について見ていきます。あまり実践で使うことは多くないので、ざっくり把握でもOKです。

テーブルAとテーブルBの全ての組み合わせ

クロス結合は、値の一致などは特に考えず、全てのレコードの組み合わせを取得する結合方法です。よって、実行結果のレコード数は膨大になります

CROSS JOINの基本構文が下記です。

SQL
SELECT カラム名
FROM テーブル名1
CROSS JOIN テーブル名2;

全てのレコードの組み合わせなので、他のJOIN句の時のようにONで条件指定をする必要がありません。

検索クエリ

SQL
SELECT *
FROM employee
CROSS JOIN department;

実行結果

idnamedepartment_ididname
1山田31営業部
2鈴木41営業部
3佐藤11営業部
4佐々木61営業部
5丸山11営業部
1山田32人事部
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

右2列を見てみると、全てid1営業部の情報になっています。まずは、departmentテーブルのid1を起点にしてemployeeテーブルの全ての組み合わせを取得しているのです。

これが、2人事部の場合、3企画部の場合、…という形で全パターンを取得してきます。

実践でよく使うのはINNER JOINLEFT OUTER JOIN

ここまで、5種類の結合を説明してきましたが、実際のデータ分析でよく使うのはINNER JOINLEFT OUTER JOINです。

INNER JOINの使いどころ

テーブルを組み合わせて表示したい時に有効なので、実践で最も使われる結合です。

例えば、従業員がどの部署に所属しているかを把握したい時に、従業員を管理するテーブルと部署を管理するテーブルをINNER JOINを使って結合することで、一覧を取得できます。

LEFT OUTER JOINの使いどころ

一つの情報を元に、全てのパターンを炙り出したい時に有効です。

例えば、ユーザーに一斉にアンケート回答をお願いしたとします。アンケート結果を分析するために、アンケートを管理するテーブルを起点にユーザーを管理するテーブルをLEFT OUTER JOINすることで、アンケートに回答していないユーザーにはNULLが保存されます。

誰がアンケートに回答していないか一目瞭然ということです。

この2つの結合方法については、必要になった時すぐに使えるように習得しておくことをおすすめします。

内容のまとめ

  • SQLのテーブル結合とは、文字通り複数のテーブルを結合すること
  • SQLで使える結合は5種類存在する
  • 内部結合のINNER JOINは、テーブルAとテーブルBのカラムの値が一致するレコードのみを取得する
  • 外部結合には、左外部結合のLEFT OUTER JOIN、右外部結合のRIGHT OUTER JOIN、完全外部結合のFULL OUTER JOINの3種類がある
  • 左外部結合のLEFT OUTER JOINは、テーブルAのレコードを全て取得した上で、テーブルBのカラムの値が一致するレコードも取得する
  • 右外部結合のRIGHT OUTER JOINは、テーブルBのレコードを全て取得した上で、テーブルAのカラムの値が一致するレコードも取得する
  • 完全外部結合のFULL OUTER JOINは、テーブルA・テーブルBそれぞれのレコードを全て取得した上で、テーブルAとテーブルBのカラムの値が一致するレコードも取得する
  • 外部結合の3つはそれぞれOUTERを省略することができる
  • クロス結合のCROSS JOINはテーブルAとテーブルBの全てのレコードの組み合わせを取得するため、実行結果のデータ量が膨大になる
  • 実践でよく使う結合方法は、INNER JOINLEFT OUTER JOINの2つ