SQL

ポケモンで解説するSQLの内部結合、外部結合

ども、シローです。

今回はSQLの内部結合と外部結合の違いについてです。

両者では最終的に抽出されるデータが異なるので要件に合わせて使い分けていきたいものです。

とりあえず結論

  • 内部結合(JOIN, INNER JOIN)は結合先に結合条件に合うデータがない場合は結合元を出力対象にしない
  • 外部結合は
    • LEFT JOIN: 結合先に結合条件に合うデータがなくても結合元だけは出力対象にする
    • RIGHT JOIN: 結合先に結合条件に合うデータがなくても結合先だけは出力対象にする(LEFT JOINの逆)

わかっている人はこのニュアンスで通じてくれるはずなので、もしパッと来なかったら次進んでくださいー

サンプルデータ

解説するにあたって、こちらのデータを用いていきます。

ポケモンってSQLの勉強に便利ですね

pokemonテーブル

pokemon_typeテーブル

 

結合元と結合先

結合には結合元結合先があります。

例えば、「pokemonテーブルにpokemon_typeを結合したい」という場合ですと

pokemonが結合元、pokemon_typeが結合先になって、

逆に、「pokemon_typeにpokemonを結合したい」という場合ですと

pokemonが結合先、pokemon_typeが結合元になります。

SQLの文法で言えば

  • FROM の後に指定するテーブルが結合元
  • JOINの後に指定するテーブルが結合先

になりますねー

では、これから内部結合と外部結合の違いについて解説していきます。

内部結合

内部結合は結合先に結合条件に合うレコードが存在しない場合には結合元のレコードを出力しません。

文法ですと、JOIN 結合先 ON 結合条件 またはINNER JOIN 結合先 ON 結合条件となります。

例えばエスパータイプのポケモンのみをpokemonテーブルから抽出したい、という場合ですと

次のように

なります。

お気づきの通り、エスパータイプではないポケモンはpokemon_typeの結合条件から外れるので抽出されてませんね。

このように結合先に結合条件に会ったレコードが存在する場合に結合元を抽出するのが内部結合です。

外部結合

外部結合にはLEFT JOINRIGHT JOINがありますが、よく使われるのはLEFT JOINの方なのでこちらを基準として解説します。

LEFT JOINRIGHT JOINは互いに逆の関係になっているという感じで大丈夫だと思ってます。(と言いつつ、別のブログ->https://sql-oracle.com/sqlserver/?p=1130

外部結合は結合条件に合致してなくても結合元のレコードを出力します。

例えば、第2タイプがないポケモンでもid, name, type1, type2(ない場合はNULL)という形式で出力したい場合は

次のように

なります。

仮に内部結合だった場合

もし、上記のSQL文のLEFT JOINJOINだった場合、すなわち内部結合だと

第二タイプがないポケモンは出力されません。

このように

  • 第二タイプのないポケモン含めて、全ポケモンのタイプを知りたい→外部結合
  • 第二タイプまであるポケモンのみ知りたい→内部結合

というふうに内部結合か外部結合かを選ぶことができますね

 

まとめ

  • 内部結合:結合先に条件にマッチしたレコードがあれば結合先も出力
  • 外部結合(LEFT JOIN):結合先に条件にマッチしたレコードがなければ結合先は出力しない

要件に合わせて使い分けていきましょー

 

基礎からのMySQL 第3版 (基礎からシリーズ)
2012年の改訂版から5年半ぶりの改訂データベースに触れるのが本当に初めてという方に向けて、「データベースとは何か」という基本中の基本から、MySQLを使ったデータベースの作成と操作、PHPとの連携によるWebアプリケーション作成の入り口までを、豊富な図とサンプルにより解説します。5年間で周辺環境が変わりましたので、そちらを一新しての刊行です。

-SQL

© 2021 Shiro's secret base