Kodokon kodokon.com

LEFT JOIN と NULL:欠けているものを見つける

LEFT JOIN でテーブルのすべての行を残し、IS NULL で不在を見つけ、COALESCE でそれを置き換えましょう。

8 分 · 3 問

このレッスンを Kodokon で開く

前のレッスンの INNER JOIN は、注文のない顧客を隠してしまいます。ところが、実務で最も多い問いはまさに、誰が欠けているのか? です。休眠中の顧客、一度も売れなかった商品、支払いのない請求書など。このスクリプトを sqliteonline.com か sqlite3 で実行しましょう。注文のない四人目の顧客を追加します。

SQL
CREATE TABLE customers (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  city TEXT
);

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL,
  amount REAL NOT NULL
);

INSERT INTO customers (id, name, city) VALUES
  (1, 'Alice', 'Lyon'),
  (2, 'Karim', 'Paris'),
  (3, 'Mina', 'Nantes'),
  (4, 'Paulo', 'Lille');

INSERT INTO orders (id, customer_id, amount)
VALUES
  (1, 1, 49.90),
  (2, 1, 15.00),
  (3, 2, 120.50);
MinaとPauloは注文をしていません。

LEFT JOIN は、右側に一致相手がなくても、左側のテーブル(キーワードの前に書かれたテーブル)のすべての行を残します。一致相手がないとき、右側のテーブルの列は NULL で埋められます。

SQL
SELECT c.name, o.id AS order_id, o.amount
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id;
MinaとPauloが、order_id と amount をNULLにして現れます。

欠けているものを取り出すには、これらの NULL 値で絞り込みます。これはアンチ結合パターンで、データ分析における欠かせない反射神経です。テストする列は右側のテーブルから来ていて、自然にNULLになることが決してないものでなければなりません。だからその主キーである o.id を選ぶのです。

SQL
SELECT c.name, c.city
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id
WHERE o.id IS NULL;
一度も注文したことのない顧客:MinaとPauloです。

最後にもう一つの道具です。COALESCE(a, b) は、a がNULLでなければ a を、そうでなければ b を返します。LEFT JOIN と集計と組み合わせると、レポートや請求書の中で、不在を使える形のゼロに変えてくれます。

SQL
SELECT c.name,
  COALESCE(SUM(o.amount), 0) AS total_spent
FROM customers AS c
LEFT JOIN orders AS o
  ON o.customer_id = c.id
GROUP BY c.id
ORDER BY total_spent DESC;
顧客ごとの支出合計。休眠中の顧客にはNULLの代わりに0を表示します。

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. 一度も注文したことのない顧客を一覧にする組み合わせはどれですか?
    • INNER JOIN のあと WHERE o.id IS NULL
    • LEFT JOIN のあと WHERE o.id IS NULL
    • LEFT JOIN のあと WHERE o.id = NULL
  2. 条件 amount = NULL は何を返しますか?
    • amount がNULLの行に対して真になる
    • 決して真にならない:比較は未定義のまま
    • 構文エラー
  3. 注文のない顧客に対して、COALESCE(SUM(o.amount), 0) は何を返しますか?
    • 0
    • NULL
    • その顧客は結果から除外される
    • 集計エラー