CodeGym /コース /SQL SELF /LEFT JOINの使い方:左側テーブルの全データを含める

LEFT JOINの使い方:左側テーブルの全データを含める

SQL SELF
レベル 11 , レッスン 2
使用可能

例えば、君が2つのテーブルを持っているとしよう:学生リストと、その学生が受講しているコースのリスト。全員がコースに登録しているわけじゃなくて、まだ何も選んでない学生もいる。全学生のリストを、コース未選択の人も含めて見たいとき、INNER JOINだとコース登録済みの人しか出てこない。じゃあ、他の学生はどうする?そこでLEFT JOINの出番だよ。

LEFT JOIN左側テーブル(クエリで最初に指定したやつ)の全行右側テーブルの対応する行を返す。もし対応がなければ、右側テーブルのカラムにはNULLが入るんだ。

LEFT JOINの書き方

SELECT
    テーブル1.カラム1,
    テーブル1.カラム2,
    テーブル2.カラム1,
    テーブル2.カラム2    
FROM 
    テーブル1 LEFT JOIN テーブル2
ON 
    テーブル1.共通カラム = テーブル2.共通カラム;
  • テーブル1 — これが「左側」テーブル。
  • テーブル2 — これが「右側」テーブル。
  • 共通カラム — 結合に使う共通のカラム。

ざっくり例

もしstudentsテーブルがこんな感じだったら:

student_id name
1 Otto
2 Anna
3 Peter

そしてenrollmentsテーブルがこう:

enrollment_id student_id course
1 1 数学
2 1 物理
3 2 生物学

このクエリを実行すると:

SELECT
    students.name, 
    enrollments.course
FROM 
    students LEFT JOIN enrollments
ON 
    students.student_id = enrollments.student_id;

結果はこうなる:

name course
Otto 数学
Otto 物理
Anna 生物学
Peter NULL

見ての通り、結果には全学生が出てくる。たとえば、まだどのコースにも登録してないSergeyもいるよ。SergeyのcourseカラムはNULLになってる。

LEFT JOINの使い方例

例1:全学生とそのコースのリストを取得

やりたいこと:全学生と、もしコースに登録していればそのコースも一緒に表示したい。まだコース未選択の学生もちゃんと出したい。

さっきと同じクエリ:

SELECT
    students.name, 
    enrollments.course
FROM 
    students LEFT JOIN enrollments
ON 
    students.student_id = enrollments.student_id;

結果:

name course
Otto 数学
Otto 物理
Anna 生物学
Peter NULL

これがLEFT JOINの典型的な使い方だね。

例2:商品とその売上を表示

例えば、君が2つのテーブルを持っているとしよう:

全部の商品が入ってるproductsテーブル:

product_id product_name
1 スマートフォン
2 タブレット
3 ノートパソコン

売上データが入ってるsalesテーブル:

sale_id product_id quantity
1 1 5
2 1 3
3 2 2

今、全商品とその売上数を見たい。まだ売れてない商品も含めてね。

SELECT
    products.product_name, 
    SUM(sales.quantity) AS total_sold
FROM 
    products LEFT JOIN sales
    ON 
    products.product_id = sales.product_id
GROUP BY 
    products.product_name;

結果:

product_name total_sold
スマートフォン 8
タブレット 2
ノートパソコン NULL

LEFT JOINを使うときの注意点・ハマりポイント

いつもNULLでいいの?
時々、LEFT JOINで思わぬところにNULLが入ることがある。そんなときはCOALESCE()関数でNULLを分かりやすい値に置き換えよう。

SELECT
    students.name, 
    COALESCE(enrollments.course, 'コース未選択') AS course
FROM 
    students LEFT JOIN enrollments
ON 
    students.student_id = enrollments.student_id;

結果:

name course
Otto 数学
Otto 物理
Anna 生物学
Peter コース未選択

いらない重複
右側テーブルに重複データがあると、クエリ結果が思ったより多くなることがある。データをよく見て、重複がいらないならDISTINCTを使おう。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION