【SQL実行例付き】内部結合と外部結合の違いは?

2019年7月31日

当サイトのリンクには広告が含まれています。

データベース操作の初学者でも内部結合は理解しやすいのですが、外部結合は少し複雑でどのようなものか正確に理解できていない方が多いです。

そんな方でも絶対に覚えられるよう内部結合と外部結合を比較しつつ解説します。

解説時にテーブルの例として以下のbookテーブルとauthorテーブルを使います。

book
author

 

database_name=# select * from book;
 id |     name     | author_id
----+--------------+-----------
  1 | 銀河鉄道の朝   |         2
  2 | 川辺のフカフ   |         1
  3 | 1Q3          |         1
  4 | 羅生藻        |         4
(4 rows)

database_name=# select * from author;
 id |     name
----+--------------
  1 | みやざわけん
  2 | 村上春根
  3 | 結婚式部
(3 rows)

PostgreSQLを使ってテーブル作成する方法を知りたい方は以下のページを参考にしてください。

結合とは

結合とは二つ以上のテーブルを一つに連結させることです。

結合のさせ方の中で特に有名なのが本記事で解説する内部結合と外部結合です。他の結合としてはクロス結合という結合の仕方もあります。

結合時のルール

結合にはルールがあります。

それは2つのテーブルを結びつける列(以後、カラム)が存在することです。

解説で利用するテーブルの場合、bookテーブルの"author_id"カラムとauthorテーブルの"id"カラムが2つのテーブルを結びつけるカラムにあたります。まだどのようなカラムかイメージがついていないと思いますが、後ほど具体例の中で説明するのでご安心ください。

この2つのテーブルを結びつけるカラムが、内部結合と外部結合を理解するためにとても重要です。

内部結合とは

内部結合は「テーブルを結びつけるカラムの値が、二つのテーブルのどちらにも存在する行だけを結合させて、どちらか片方にしかない行は捨てる」という結合方法です。

具体例を見てみましょう。

内部結合例

bookテーブルとauthorテーブルを内部結合すると以下のようなテーブルが出来上がります。

# SQL文の意味:
# 「book.author_idとauthor.idを目印にしてbookテーブルとauthorテーブルを内部結合して、全カラム取得する」

database_name=# select * from book inner join author on book.author_id = author.id;
 id |     name     | author_id | id |     name
----+--------------+-----------+----+--------------
  2 | 川辺のフカフ   |         1 |  1 | みやざわけん
  3 | 1Q3          |         1 |  1 | みやざわけん
  1 | 銀河鉄道の朝   |         2 |  2 | 村上春根
(3 rows)

2つのテーブルを結びつけるカラムであるbook.author_idの4はauthor.idカラムに存在せず、またauthor.idの3はbook.author_idカラムに存在しないため、捨てられています。

外部結合とは

外部結合は「内部結合して出来たテーブルに加えて、基準となるテーブルにしか2つのテーブルを結びつけるカラムの値が存在しない行もくっつける」という結合方法です。

例を見てみましょう。

database_name=# select * from book left outer join author on book.author_id = author.id;
 id |     name     | author_id | id |     name
----+--------------+-----------+----+--------------
  2 | 川辺のフカフ   |         1 |  1 | みやざわけん
  3 | 1Q3          |         1 |  1 | みやざわけん
  1 | 銀河鉄道の朝   |         2 |  2 | 村上春根
  4 | 羅生藻        |         4 |    |
(4 rows)

上三行は先ほどの内部結合の結果と同じだが、一行増えています。これが外部結合による効果です。

“基準ではないテーブル"にないカラムの値は、Null(値なし)になっています。

基準となるテーブルは外部結合のさせ方によって変わります。
左外部結合ならSQL文の左の方に書かれているテーブル(今回だとbook)が基準に、
右外部結合ならSQL文の右の方(joinの後)に書かれているテーブルが基準になります。

今回は"left outer join"という形で左外部結合を行なっており、
bookテーブルが基準のためこのような結果になりましたが、
authorテーブルが基準になった場合は結果が変わります。

内部結合と外部結合の結果の差が分かりやすくなるように、SQL文の実行結果を上下に並べてみます。

# 内部結合
database_name=# select * from book inner join author on book.author_id = author.id;
 id |     name     | author_id | id |     name
----+--------------+-----------+----+--------------
  2 | 川辺のフカフ   |         1 |  1 | みやざわけん
  3 | 1Q3          |         1 |  1 | みやざわけん
  1 | 銀河鉄道の朝   |         2 |  2 | 村上春根
(3 rows)

# 外部結合
database_name=# select * from book left outer join author on book.author_id = author.id;
 id |     name     | author_id | id |     name
----+--------------+-----------+----+--------------
  2 | 川辺のフカフ   |         1 |  1 | みやざわけん
  3 | 1Q3          |         1 |  1 | みやざわけん
  1 | 銀河鉄道の朝   |         2 |  2 | 村上春根
  4 | 羅生藻        |         4 |    |
(4 rows)

「外部結合 = 内部結合の結果 + 基準のテーブルにしかない行」ということがよくわかりますね。

まとめ

外部結合を理解するには内部結合もセットで理解する必要があります。

この記事で内部結合と外部結合がどのようなものなのか理解してもらえたら嬉しいです。