MySQLの内部結合に続き、外部結合を見ていきます。 内部結合との違いをしっかり理解して使い分けられるようになりましょう。 内部結合と外部結合の違いに関してはこちらから

MySQLの外部結合

3年以上前に更新されました。情報が古い可能性があります。
更新日 : 2019年06月19日

MySQLの内部結合に続き、外部結合を見ていきます。

内部結合との違いをしっかり理解して使い分けられるようになりましょう。

内部結合と外部結合の違いに関してはこちらから

外部結合の書式

SELECT
	カラム名1,
	カラム名2,
	...
FROM
	データベース名.左テーブル名
LEFT (OUTER) JOIN
	データベース名.右テーブル名
	ON
		結合条件
(WHEREなど)

書式は上記の通りです。OUTER句はなくてもOKです。LEFT JOINで左外部結合になります。

右外部結合は下のようになります。

SELECT
	カラム名1,
	カラム名2,
	...
FROM
	データベース名.左テーブル名
RIGHT (OUTER) JOIN
	データベース名.右テーブル名
	ON
		結合条件
(WHEREなど)

実際に外部結合でデータを取得してみる

前回の内部結合の記事で利用したテーブルデータをそのまま利用して外部結合を試してみます。

使用するデータは以下のような形でした。

左外部結合で取得してみる

早速以下のSQLを実行してみましょう。

SELECT
	*
FROM
	goods
	LEFT JOIN
		categories
		ON
		categories.id = goods.category_id;

今回はgoodsテーブルを基準としてcategoriesテーブルを結合しています。そのため、goodsテーブルはすべて取得できた上でcategoriesが存在しなかった場合にはNULLとなります。NULLはデータが存在しないという意味です。

内部結合と違い、このようにデータが存在しないカラムがあることが特徴です。

今度は逆に右外部結合で取得してみましょう。

右外部結合で取得してみる

以下のSQLを実行しましょう。

SELECT
	*
FROM
	goods
	RIGHT JOIN
		categories
		ON
		categories.id = goods.category_id;

実行結果は以下のようになります。

今度は右外部結合なので、右のテーブルであるcategoriesテーブルが基準になります。

そのため、categoriesテーブルのレコードはすべて取得され、goodsテーブルのデータが存在しない可能性があります。今回の結果であれば、goodsテーブルには家具のカテゴリーに該当する商品が存在しないため、NULLとなります。

条件や取得するカラムを指定してみる

外部結合から応用して取得するカラムを制限したり、取得条件を制限してみましょう。

例えば、5万円以上の商品の商品名・価格・カテゴリー名を、goodsテーブルを基準に取得すると以下のようなSQLになります。

SELECT
	goods.name,
	goods.price,
	categories.category_name
FROM
	goods
	LEFT JOIN
		categories
		ON
		categories.id = goods.category_id
WHERE
	goods.price >= 50000;

実行結果は以下のようになります。

今回は左外部結合でgoodsテーブルを基準としましたが、goodsテーブルを基準とする外部結合だと以下のようなSQLで書き換えることも可能です。

SELECT
	goods.name,
	goods.price,
	categories.category_name
FROM
	categories
	RIGHT JOIN
		goods
		ON
		categories.id = goods.category_id
WHERE
	goods.price >= 50000;

これでも実行結果は同じです。〜〜 JOIN句の前に書いてあるテーブルを左テーブル、後に書いてあるテーブルを右テーブルと認識するだけなのでどちらのSQLを実行しても構いません。

ただ、日本人としては前に書いた内容を基準としたほうが読みやすい気がします。英語圏の人の感覚はわかりません(笑)

まとめ

内部結合と違い、データが存在しない場合があることに注意しましょう。

NULLはプログラムだと非常に扱いづらい状態なので、外部結合を利用する際にはプログラムのコード側を注意して作成する必要があります。

また、内部結合と同様にFROM句以降の

categories
	RIGHT JOIN
		goods
		ON
		categories.id = goods.category_id

という部分全体が1つのテーブルとして見てあげるとわかりやすいかと思います。