Help us understand the problem. What is going on with this article?

【SQL入門】最適なテーブル結合について

この記事では、《テーブル結合》について、
業務を通して学習した内容を、備忘録としてまとめています。

  • テーブル結合のロジック
  • 最適な結合方法

こういった内容についてまとめています。

※本記事は、自分で学習したことのまとめ用として書いています。
尚、解説で誤った点があれば、スローして頂ければ喜んでキャッチしますのでお願い致します。

テーブル結合のロジック

shells_script_3.jpg

まずは・・・

"どう言う流れでテーブルが結合がされるか"

を理解する必要があります。

そして、流れは下記の通りです。

  1. ON句の条件で、テーブルを結合する
  2. WHERE句の条件で、抽出する

--- 具体例(内部結合) ---

『内部結合』は・・・

それぞれのテーブルで、ON句で指定したカラムの値が一致するものだけを結合します。

『内部結合』_の命令には、INNER JOINを使います。

person テーブル

id name job_id
1 A 1
2 B 2
3 C 3

job テーブル

id job_name
1 engineer
2 designer


では・・・

上記2つのテーブルを例に、『テーブル結合のロジック』について見ていきましょう。

パターン①: ON句のみ

SELECT
    id,
    person.name,
    job.job_name
FROM person
    INNER JOIN job
        ON person.job_id = job.id

-- job.idはjobのPK
結果
id name job
1 A engineer
2 B designer

ON句で指定したperson.job_id = job.idという条件で、テーブル結合しています。

また・・・

job テーブルに id = 3のレコードがないため、Cのレコードは削除されています。

パターン②: ON句とWHERE句

SELECT
    id,
    person.name,
    job.job_name
FROM person
    INNER JOIN job
        ON person.job_id = job.id
WHERE 
    job.id = '1';

-- job.idはjobのPK
結果
id name job
1 A engineer

パターン①の条件に加え、WHERE句job.id = '1'を指定しているので…

Bのレコードが削除されています。

LEFT OUTER JOINで気をつけること

shells_script_1.jpg

--- 処理の概要 ---

LEFT OUTER JOINでは・・・

LEFT OUTER JOINの)左側のテーブルの行を全て抽出します。

そのため・・・

右側のテーブルに存在しない行については、NULLが埋められています。

ちなみに・・・

先ほどのコードを、LEFT OUTER JOINで書き換えると…

SELECT
    id,
    person.name AS name,
    job.job_name AS job
FROM person -- ←左側
    LEFT OUTER JOIN job -- ←右側
        ON person.job_id = job.id

-- job.idはjobのPK

となります。

その結果・・・

例えば、下記のようなデータが取れる可能性もあります。

id name job
1 A engineer
2 B NULL
3 C NULL

繰り返しになりますが、結合処理のロジックは…

  • ON句の条件で、テーブルを結合する

であるので、この後に、左側のテーブルの行を全て呼び出します。

その結果・・・

" 取得する必要ない行にNULLが埋められて、呼び出される "

という訳です。

--- NULL対策 ---

WHERE句の条件で、抽出する

SELECT
    id,
    person.name AS name,
    job.job_name AS job
FROM person
    LEFT OUTER JOIN job
        ON person.job_id = job.id
WHERE 
    job.id = '1';

-- job.idはjobのPK

上記のように・・・

WHERE句の条件で、抽出することでNULLを回避することができます。

id name job
1 A engineer

最適な結合方法

career-3.jpg

しかし、先ほどのコードだと・・・

仮に…

" 100万件を超える大量のデータを持つテーブル同士を結合させる "

といった場合、処理が遅くなってしまいます。

100万件のデータを結合した後に、WHERE句の条件で抽出するためです。

なので、大量のデータの場合は…

" 結合する前に、必要なデータのみを抽出しておく "

のがオススメです。

WITH variation AS(
    SELECT *
    FROM
        person
    WHERE
        person.job_id = '1'
)

SELECT
    id,
    person.name AS name,
    job.job_name AS job
FROM variation
    LEFT OUTER JOIN job
        ON person.job_id = job.id

上記のSQLでは・・・

  1. サブクエリの処理
    ➡︎ この時点で、person.job_id = '1'を抽出する
  2. ON句で結合

といった処理の流れとなります。

" サブクエリを使って、あらかじめ必要なデータのみを抽出して、結合する件数を減らす。 "
ということをしています。

これにより・・・

無駄なテーブル結合を削減できるうえ、左側(person)のテーブルはサブクエリによって抽出済みのため、

仮に、LEFT OUTER JOINによって全行呼び出されたとしても…

最終的に取得できる結果は、`person.job_id = '1'のレコードのみになります。

id name job
1 A engineer
yaaabu51
明石高専 → 某重工で4年間ガスタービンの生産技術とか → 退職 →1年勉強(ふらふら)→ IT業界1年生
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした