こう 聞かれます
- 「INNER JOIN と LEFT JOIN の
違いを 説明してください」 - 「注文が 1 件も
無い 顧客も 一覧に 出したい とき、 どう 書きますか」 - 「JOIN したら
行の 数が 増えたのは なぜですか」
面接官が 見ている点
- 「相手の
無い 行が 残るか どうか」を、例で示せるか - LEFT JOIN で
相手の 無い 行には NULL が 入る、 と分かっているか - 1 対多の
結合で、 行が 増える ことに 気づけるか
短い答え
- INNER JOIN は、
結合の 条件に 合う 相手が いる 組み合わせだけを 返します。 - LEFT JOIN は、
左の 表の 行を 全部残し、 相手が いない 行は 右の 表の 列を NULL (空の 値) で 埋めます。 - 1 人に
注文が 2 件 あれば 2 行に なるので、 どちらの 結合でも、 相手が 多い側に 合わせて 行が 増えます。
少し 詳しい答え
同じ 表で比べる
顧客が 2 人いて、
SQL クエリ
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(20)
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
item VARCHAR(20)
);
INSERT INTO customers VALUES
(1, '佐藤'),
(2, '鈴木');
INSERT INTO orders VALUES
(1, 1, 'ペン'),
(2, 1, 'ノート');
SELECT c.name, o.item
FROM customers c
INNER JOIN orders o
ON o.customer_id = c.id
ORDER BY o.id;佐藤|ペン
佐藤|ノートINNER JOIN では、
SQL クエリ
SELECT c.name, o.item
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
ORDER BY c.id, o.id;佐藤|ペン
佐藤|ノート
鈴木|LEFT JOIN では
件数を数える
顧客ごとの
SQL クエリ
SELECT c.name, COUNT(o.id)
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
GROUP BY c.id, c.name
ORDER BY c.id;佐藤|2
鈴木|0COUNT(o.id) は NULL をCOUNT(*) に
作った
よく ある間違い
- 「LEFT JOIN は
左の 表の 行数のまま」と言う 相手が 何件も あれば、 その 数だけ行が 増えます。 変わらないのは、 左の 行が 消えないことです - LEFT JOIN の
あと、 右の 表の 条件を WHERE に置く た とえば WHERE o.item = 'ペン'にすると、 NULL の 行は 条件に 合わず 消え、 INNER JOIN と 同じ 結果に なります。 右の 表を 絞るなら ON に書きます - 0 件の
人を 数えるのに COUNT(*)を使う 相手の無い 行も 1 行として 数えるので、 0 ではなく 1 になります
深掘りの問い
- 「RIGHT JOIN との違いは」残す側が
右の 表に なるだけです。 表の 順を 入れ替えれば LEFT JOIN で 書けるので、 読みやすさの ため LEFT に そろえる、と答えます - 「注文が 1 件でもある
顧客だけを、 行を 増や さずに 出すには」 EXISTS で、 相手が いるかだけを 調べる、と答えます - 「結合したら合計の
金額が 大きくなりすぎました。 なぜですか」 1 対多の 表を 2 つ同時に 結合すると、 行が 掛け算で 増えて 同じ 金額を 何度も 足すため、と 答えます。 先に それぞれ集計してから 結合します