アンチパターンの本を読んでいてINNER JOINとOUTER JOINが曖昧だなと思ったのでこれを機にアウトプットして定着させようと思いまとめていきます。
テーブル作成
下のようにサンプルテーブルを2つ用意しました。
shohinsテーブル
shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | siire_tanka | torokubi |
0001 | Tシャツ | 衣服 | 1000 | 500 | 2009-09-20 |
0002 | 穴あけパンチ | 事務用品 | 500 | 320 | 2009-09-11 |
0003 | カッターシャツ | 衣服 | 4000 | 2800 | NULL |
0004 | 包丁 | キッチン用品 | 3000 | 2800 | 2009-09-20 |
tenpo_shohinsテーブル
tenpo_id | tenpo_mei | shohin_id | suryo |
000A | 東京 | 0002 | 30 |
000A | 東京 | 0001 | 50 |
000B | 名古屋 | 0002 | 30 |
INNER JOINの場合
SELECT * FROM shohins s INNER JOIN tenpo_shohins ts ON s.shohin_id = ts.shohid_id;
shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka | torokubi | tenpo_id | tenpo_mei | shohin_id | suryo |
0001 | Tシャツ | 衣服 | 1000 | 500 | 2009-09-20 | 000A | 東京 | 0001 | 50 |
0002 | 穴あけパンチ | 事務用品 | 500 | 320 | 2009-09-11 | 000A | 東京 | 0002 | 30 |
0002 | 穴あけパンチ | 事務用品 | 500 | 320 | 2009-09-11 | 000B | 名古屋 | 0002 | 30 |
結果を見ると分かるようにもともとあったshohin_idが0003と0004のレコードが消えているのが分かります。また、0002のレコードが増えているのが分かります。shohinsテーブルのshohin_idとtenpo_shohinsテーブルのshohin_idが一致したもののみを返すことが分かります。これにより、元テーブルのレコードが消えることも増えることもあることが分かりました。
LEFT OUTER JOINの場合
SELECT s.shohin_id, s.shohin_mei, ts.tenpo_id, ts.tenpo_mei FROM shohins s LEFT OUTER JOIN tenpo_shohins ts ON s.shohin_id = ts.shohin_id;
shohin_id | shohin_mei | tenpo_id | tenpo_mei |
0002 | 穴あけパンチ | 000A | 東京 |
0001 | Tシャツ | 000A | 東京 |
0002 | 穴あけパンチ | 000B | 名古屋 |
0003 | カッターシャツ | NULL | NULL |
0004 | 包丁 | NULL | NULL |
結果を見ると結合できなかった行に関してはNULLが挿入されていることと、shohin_idが0002のレコードが重複していることが分かります。INNER JOINとはちがい、基準となるテーブル(この場合、LEFT OUTER JOINなので、shohinsテーブル)のレコードは必ず残ることが保証されることが分かります。ちなみにRIGHT OUTER JOINをした場合の結果がこちらです。
shohin_id | shohin_mei | tenpo_id | tenpo_mei |
0001 | Tシャツ | 000A | 東京 |
0002 | 穴あけパンチ | 000A | 東京 |
0002 | 穴あけパンチ | 000B | 名古屋 |
この場合、tenpo_shohinsテーブルが必ず残り、一致しなかったshohinsテーブルの値は残りません。
さいごに
INNER JOINを使う場合は意図せずレコードが消えてしまう場合があることと、どちらの場合もレコードの重複には注意が必要だということが分かりました。
ここまで読んでいただきありがとうございました。よいSQLライフを。