初心者は間違いやすいかも。まとめてみた。
まずはjoinとleft joinの説明
これからtable1、2を結合していく。共通カラム:Noで結合。
table1
No | 名前 | 年齢 |
---|---|---|
1 | 田中 | 10 |
2 | 木村 | 56 |
3 | マイケル | 124 |
table2
No | 趣味 | 性別 |
---|---|---|
2 | (null,つまりデータ無し) | 男 |
3 | バスケットボール | 女 |
JOINの結果
No | 名前 | 年齢 | 趣味 | 性別 |
---|---|---|---|---|
2 | 木村 | 56 | (null,つまりデータ無し) | 男 |
3 | マイケル | 124 | バスケットボール | 女 |
joinは結合条件が一致しないレコードは表示されない。
left joinの結果
No | 名前 | 年齢 | 趣味 | 性別 |
---|---|---|---|---|
1 | 田中 | 10 | (null) | (null) |
2 | 木村 | 56 | (null) | 男 |
3 | マイケル | 124 | バスケットボール | 女 |
No1に関して、joinでは丸ごと消えるが、left joinではnullとして結合される。
結合条件が一致してなくても全レコード表示させたいときにleft joinを使うとnullで結合される。
left join 内にwhere(抽出条件)を書くことで該当するものだけを表示し、該当外をnullにできる。
以下だと、性別=男だけを表示するので、バスケットボールと女の部分がnullとなる。
left join(select * from table2 where 性別 = '男') on table2.No = table1.No
絞るほどnullが増えていく。
left jon時の注意点。共通カラムが重複レコード存在するパターン
left join 内にwhere(抽出条件)を書くのは危険な場合がある。
例えば、上のテーブルで 性別=男 と絞り、抽出したが
No=3 にもう一人いて、その人が男である場合も含まれない。
where 性別 = '男'
、はNo3女とNo3男があるときNo3男側は表示されると思うが、
1つのNoに男女両方いるレコードは含まれない。
結合条件がon table2.No = table1.No
つまり No3に男以外がいるじゃん!となってNo3全てnullとなってしまう。
(結合条件が主キーとか重複しない一意な項目なら問題ない)
例:1つのNoに男女ともいるtable2
No | 住人 | 趣味 | 性別 |
---|---|---|---|
1 | 1 | サバゲー | 男 |
2 | 1 | (null,つまりデータ無し) | 男 |
3 | 1 | バスケットボール | 女 |
3 | 2 | ソフトボール | 男 |
対応
left join内のwhereで指定せず、両テーブルの全てのレコードを結合してから最後にwhereで絞る!
パターンを使い分けよう。
おまけ 内部結合と外部結合
今回説明したjoinのように結合条件が一致しないレコードは表示されないのが内部結合。
left joinのように結合条件が一致してなくても全レコード表示されるのが外部結合。
joinは正しくはinner joinと呼ばれる。
left joinはは正しくはleft outer joinと呼ばれる。
外部結合にはもう1種類あってright join(正しくはright outer join)がある。
left joinとright joinの違い
select * from table1 〇〇join table2
とあるとき。左がtable1で、右はtable2のように見える。
left joinだとtable1が優先表示される。
[left joinの結果](#left join)の結果を見ると、table1は全て表示されtable2にないレコードはnullで結合される。
right joinだとtable2が優先表示される。
[left joinの結果](#left join)の結果を見ると、table1は全て表示されtable2にないレコードはnullで結合される。
これが逆になり、table2は全て表示されtable1にないレコードはnullで結合される。