リレーショナルデータベース学習の難所、外部結合と内部結合の違いとは? | サービス | プロエンジニア

    リレーショナルデータベース学習の難所、外部結合と内部結合の違いとは?

    • このページをはてなブックマークに追加

    公開日:2017年01月17日 最終更新日:2019年09月27日

    リレーショナルデータベースの基礎を学ぶ際に、多くの方がもやもやを抱えやすいのが外部結合と内部結合の違いについてかと思います。今回は、リレーショナルデータベースの3つの基本操作から始まり、結合方法の種類と違いについてご紹介したいと思います。

    目次

    1.リレーショナルデータベースの3つの基本操作

    リレーショナルデータベースの表操作には、主に3つの操作があります。それは「選択(SELECTION)」「射影(PROJECTION)」「結合(JOIN)」です。

    1.1 選択とは

    選択とは、表(テーブル)の中から指定した条件に沿った「行(レコード)」を抽出する操作のことです。

    column_image6462_01

    上図のように社員一覧から開発課に所属する社員のレコードのみを抽出する場合、SQLは次のように書くことができます。


    SELECT * FROM 社員一覧 WHERE 所属部署 = '開発課'; (※注1)


    (※注1)「*」とは

    「*」は「対象テーブルの全カラム名」を示します。今回は「社員番号, 氏名, 等級, 所属部署」と記載するのと同等の扱いになります。

    ▲目次へ戻る

    1.2 射影とは

    射影とは、表の中から指定した条件に沿った「列(カラム)」を抽出する操作のことです。

    column_image6462_02

    上図のように社員一覧から指名と所属部署に属するデータのみを抽出する場合、SQLは次のように書くことができます。


    SELECT 氏名, 所属部署 FROM 社員一覧;


    ▲目次へ戻る

    1.3 結合とは

    結合とは、2つ以上の表(テーブル)を共通の値を持つ列(カラム)をキーに、くっつけて一つの表にしてしまうことです。

    column_image6462_03

    上図のように「所属部署」をキーに「社員一覧」と「部署マスタ」を結合する場合、SQLは次のように書くことができます。


    SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
       部署マスタ.所属部署, 部署マスタ.部署名称
      FROM 社員一覧, 部署マスタ
      WHERE 社員一覧.所属部署 = 部署マスタ.所属部署;


    対象となるテーブルが1つだけだった選択や射影と違い、結合の場合はどちらのテーブルに属するカラム名かを特定するために「テーブル名.カラム名」と書く必要があります。

    ちなみに、社員一覧の「所属部署」と、部署マスタの「所属部署」は、それぞれカラム名が異なっていても結合することが可能です。さらにSELECTの後の要素の指定を「*」にした場合、FROMの後に書かれた順に全ての要素が羅列されます。

    カラム名が異なり、かつ「*」を指定した場合は、次のようなSQLとその実行結果になります。


    SELECT *
      FROM 社員一覧, 部署マスタ
      WHERE 社員一覧.所属部署 = 部署マスタ.所属コード;


    column_image6462_04

    今回の記事ではこの「結合」をメインに、さらに掘り下げていきたいと思います。

    ▲目次へ戻る

    2.内部結合(INNER JOIN)の概要と書き方

    2.1 内部結合とは

    実は、前述した「結合(JOIN)」と「内部結合(INNER JOIN)」の実行結果は、全く同じになります。内部結合は記述を省略することが可能で、省略したものが先ほど「結合」の項目でご紹介した記述例のようなSQLになります。

    なお内部結合(INNER JOIN)には、「指定したカラムの値が一致するレコードのみを抽出する」という特徴があります。つまり、どちらかにないレコードは抽出対象になりません。(もちろん同じ結果が得られる「結合」でも、一致しないレコードがあれば結果に抽出されないのは一緒です)

    ▲目次へ戻る

    2.2 MySQLを使用する場合の内部結合の構文例

    省略せずに内部結合としてきちんと記述した場合、次のようになります。(なお今回MySQLを例にとっていますが、このあたりは基本のため多くのRDBMSで同じ構文が使用可能です)


    SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
       部署マスタ.所属コード, 部署マスタ.部署名称
      FROM 社員一覧
      INNER JOIN 部署マスタ
      ON 社員一覧.所属部署 = 部署マスタ.所属コード;


    column_image6462_05

    このように、「所属部署」の値が「部署マスタ」に存在しない「社員E」のレコードは、内部結合では抽出対象外になります。

    ▲目次へ戻る

    3.外部結合(OUTER JOIN)の概要と書き方

    3.1 外部結合とは

    一致するもののみを対象とする内部結合に対し、外部結合は一致するものがないレコードも抽出対象とすることが可能です。

    ▲目次へ戻る

    3.2 OUTER JOINはLEFT・RIGHT・FULLの3種類

    外部結合には、「LEFT OUTER JOIN」と「RIGHT OUTER JOIN」「FULL OUTER JOIN」の3種類があります。

    ■LEFT OUTER JOINとは

    LEFT OUTER JOINでは、2つのテーブルのうち「FROM」で指定した方のテーブルを基準として、「JOIN」で指定した方のテーブルのうち該当レコードをくっつけるという処理を行います。

    ■RIGHT OUTER JOINとは

    RIGHT OUTER JOINでは、2つのテーブルのうち「JOIN」で指定した方のテーブルを基準として、「FROM」で指定した方のテーブルのうち該当レコードをくっつけるという処理を行います。テーブルの指定が逆になるだけ(テーブルを入れ替えたら同じ結果になる)なので、一般的にLEFT OUTER JOINを利用するケースが大半です。

    ■FULL OUTER JOINとは

    FULL OUTER JOINでは、2つのテーブルにある全てのレコードを抽出対象とします。お互いに存在しない部分には、「NULL」が入ります。

    ▲目次へ戻る

    ■LEFT OUTER JOINの場合

    LEFT OUTER JOINでテーブルを抽出するSQLを書くと、次のようになります。


    SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
       部署マスタ.所属部署, 部署マスタ.部署名称
      FROM 社員一覧
      LEFT OUTER JOIN 部署マスタ
      ON 社員一覧.所属部署 = 部署マスタ.所属部署;


    column_image6462_06

    このように「社員一覧」のレコードは全て抽出対象となり、取得できなかった「社員E」に対応する「部署コード」と「部署名称」の空欄は、NULLで埋められました。

    ■RIGHT OUTER JOINの場合

    RIGHT OUTER JOINでテーブルを抽出するSQLは、LEFTをRIGHTに書き換えるだけです。


    SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
       部署マスタ.所属部署, 部署マスタ.部署名称
      FROM 社員一覧
      RIGHT OUTER JOIN 部署マスタ
      ON 社員一覧.所属部署 = 部署マスタ.所属部署;


    column_image6462_07

    このように「部署マスタ」のレコードは全て抽出対象となり、取得できなかった「人事課」に対応する「社員番号」「氏名」「等級」の空欄は、全てNULLで埋めた結果が出力されました。

    ■FULL OUTER JOINの場合

    FULL OUTER JOINでテーブルを抽出するSQLは、こちらもLEFTをFULLに書き換えるだけです。


    SELECT 社員一覧.社員番号, 社員一覧.氏名, 社員一覧.等級,
       部署マスタ.所属部署, 部署マスタ.部署名称
      FROM 社員一覧
      FULL OUTER JOIN 部署マスタ
      ON 社員一覧.所属部署 = 部署マスタ.所属部署;


    column_image6462_08

    このようにFULL OUTER JOINでは、「社員一覧」「部署マスタ」のレコードは全て抽出対象となります。取得できなかった項目には、LEFTやRIGHT同様にNULLで埋められた状態で出力されました。

    ▲目次へ戻る

    4.結局、内部結合と外部結合の違いとは?

    これらの説明からお察しであると思いますが、内部結合と外部結合の違いをまとめると次のようになります。

    ・内部結合は、一致するレコードのみ抽出する
    ・外部結合は、一致しないレコードも抽出する

    業務でSQLを組んでいると、内部結合や外部結合の使い分けは必須になります。この機会にぜひ覚えておいてみて下さいね。

    年収350万円〜650万円
    勤務地 東京都 中央区
    年収350万円〜700万円
    勤務地 東京都 千代田区
    月額単価40万円〜
    勤務地 東京都 渋谷区
    年収300万円〜
    勤務地 東京都 中央区
    • このページをはてなブックマークに追加

    おすすめ記事

  • ピックアップ

    正社員

    【Oracle】データベースエンジニア|企業様向けのデータベースの構築

    年収 :350万円〜650万円

    ■業務内容■ 企業様向けのデータベース関連業務: データベース診断、コンサル、設計、構築、移行、性...

    株式会社 システムエグゼ

    正社員

    【SQL/Java】データサイエンティスト|ビッグデータの分析・コンサルティング

    年収 :350万円〜700万円

    【仕事内容】 ビッグデータを貯めるインフラの構築、溜まったデータの分析、仮説、検証、レポート作成...

    チームラボ株式会社

    フリーランス

    【SQL】ファッションアプリのデータサイエンティスト★週3日~

    月額単価 :40万円〜

    手持ちの服からコーデを自動で提案してくれるファッションアプリのデータサイエンティスト業務を担当し...

    正社員

    【Oracle】データベースエンジニア|Oracle製品での設計・構築

    年収 :300万円〜

    【業務内容】 A. Oracle製品での設計・構築・チューニング B. Oracle運用管理

    株式会社VITA