3つ以上のテーブルをJOINする
JOINを連結し、中間結果セットについて考える方法を学びます。
「3つ以上のテーブルをJOINする」はCoddyKit上の無料SQL Interview Prepレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Interview Prepコースには全4レッスンが含まれています。
結合は分岐ではなく連鎖する
実際の面接問題が2つのテーブルだけで終わることは、ほとんどありません。3つ、4つ、それ以上のテーブルを結合するよう求められます。複雑さを整理する重要な考え方は、複数テーブルの結合は、2テーブルの結合を順番に行うだけだということです。
データベースはまず最初の2つを中間結果に結合し、その結果を3つ目のテーブルに結合するという処理を繰り返します。1つの結合について考えられるなら、その連鎖についても考えられます。
3テーブルスキーマ
例を3つ目のテーブルまで拡張します。これで、顧客、顧客の注文、そして各注文が参照する商品を扱います。
customers(id, name)orders(id, customer_id, product_id, amount)products(id, title)
これらを結ぶリレーションシップは2つあります。orders.customer_id = customers.id と orders.product_id = products.id です。
customers(id, name)
orders(id, customer_id, product_id, amount)
products(id, title)基本的な3テーブルクエリ
JOINを順番に重ねます。それぞれの JOIN ... ON はテーブルを1つ追加し、それまでのテーブルとどのようにつながるかを示します。
上から下へ読みます。まず orders から始め、一致する顧客を結合し、次に一致する商品を結合します。すべての注文行に、顧客名と商品タイトルが追加されます。
SELECT c.name, p.title, o.amount
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN products p ON p.id = o.product_id;中間結果セットで考える
複数テーブルの結合を簡単にする考え方は、各JOINの後で、それまでの中間結果を思い浮かべることです。
- 1回目の結合後: orders + 顧客の列
- 2回目の結合後: その結果 + 商品の列
次のON句では、中間セットにすでに存在する任意の列を参照できます。そのため、結合の順序によって各ON句に記述できる内容が変わります。
各ON句から先行するテーブルが見える
重要な帰結があります。後続の結合のON句では、追加するテーブルだけでなく、それより前に結合した任意のテーブルを参照できます。
ここでは、3つ目の結合が、すでにスコープ内にある o(orders)とつながっています。c と p もすでに途中までの結果に含まれているため、4つ目のテーブルをどちらかに結合することもできます。
SELECT c.name, p.title, w.region
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN products p ON p.id = o.product_id
JOIN warehouses w ON w.id = o.warehouse_id; -- refers to o中心となるテーブルから始める
ライブ面接で役立つ実践的なコツは、FROMをファクト/中心テーブル(通常はリレーションシップの中央にあるテーブル)から始め、そこからルックアップテーブルへ向かって広げることです。
Orders は customers と products の両方への外部キーを持つ中心に位置するテーブルなので、ここから始めると、すべてのON句をシンプルに先行参照の形で書けます。
-- orders is central: it links to both sides
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN products p ON p.id = o.product_id連鎖全体でファンアウトが累積する
ファンアウトについて学んだことはすべて引き続き当てはまり、しかも累積します。各注文に複数の商品があり、各商品に複数の税行がある場合、行数は各段階で掛け合わされます。
複数の結合を含むクエリで集計値が大きすぎる場合は、途中の結合のどれかでファンアウトが発生していないかを疑い、各結合の粒度を個別に確認してください。
-- rows = orders * items_per_order * tax_rows_per_item
SELECT o.id
FROM orders o
JOIN order_items i ON i.order_id = o.id
JOIN item_taxes t ON t.item_id = i.id;連鎖の中で結合タイプを混在させる
1つのクエリでINNER JOINとLEFT JOINを組み合わせることはできますが、順序が重要です。LEFT JOINによってNULLが導入された後、そのNULL列を参照する後続のINNER JOINによって、保持されていた行が削除されることがあります。
この例では、注文のない顧客はLEFT JOINによってNULLの product_id とともに保持されますが、続く products へのINNER JOINによって再び除外されます。プレッシャーのかかる場面では、起こしやすいミスです。
SELECT c.name, p.title
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
JOIN products p ON p.id = o.product_id;
-- the INNER products join can cancel the LEFT JOIN外部結合を外部結合のまま保つ
注文のない顧客を最後まで保持するには、後続の結合もLEFTにします。そうすれば、NULLが安全に最後まで流れます。
経験則として、いったん外部結合にしたら、任意ブランチから派生するすべてのテーブルについて外部結合のままにしてください。
SELECT c.name, p.title
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
LEFT JOIN products p ON p.id = o.product_id;
-- customers with no orders are now kept (NULL title)規模が大きくなるとエイリアスが不可欠になる
4つまたは5つのテーブルを扱うと、複数のテーブルが id、name、created_at のような列名を共有することがあります。短く一貫したエイリアスを使うと、曖昧さを防ぎ、クエリを読みやすくできます。
テーブルを示すエイリアス(c、o、p)を選び、すべての列を修飾してください。面接官は、エイリアスの付け方から、本番用SQLをどのように書くかを判断します。
SELECT c.id AS customer_id,
o.id AS order_id,
p.id AS product_id,
p.title
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN products p ON p.id = o.product_id;多対多の関係にブリッジテーブルを使う
2つのエンティティが多対多の関係にある場合、その間に3つ目の中間(ブリッジ)テーブルを置き、そのテーブルを介して結合します。学生とコースは enrollments を介してつながります。
ブリッジテーブルを経由する必要があると見抜くこと自体が、面接でよく見られる評価ポイントです。
SELECT s.name, c.title
FROM students s
JOIN enrollments e ON e.student_id = s.id
JOIN courses c ON c.id = e.course_id;クイックチェック
結合タイプが混在する連鎖について考えてみましょう。
まとめ: 3つ以上のテーブルを結合する
面接では次の点を押さえておいてください。
- 複数テーブルの結合は2テーブル結合の連鎖です。各段階の後で中間結果について考えてください。
- 後続のON句では、連鎖内の先行する任意のテーブルを参照できます。
- 中心テーブルから始め、ルックアップテーブルへ広げていきます。
- 結合をまたぐとファンアウトが累積するため、各段階で粒度を確認してください。
- LEFT JOINの後にINNER JOINを置くと、LEFT JOINの効果を打ち消すことがあります。任意の行を保持するには、外部結合のままにしてください。
- 多対多の関係はブリッジテーブルを介して結合します。
よくある質問
「3つ以上のテーブルをJOINする」レッスンは無料ですか?
はい。「3つ以上のテーブルをJOINする」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Interview Prepコースには全4レッスンが含まれています。
「3つ以上のテーブルをJOINする」で何を学びますか?
JOINを連結し、中間結果セットについて考える方法を学びます。 ブラウザで直接実行するハンズオンコードでSQL Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Interview Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「3つ以上のテーブルをJOINする」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Interview Prepレッスンでコードを書いて実行できますか?
はい。すべてのSQL Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- INNER JOINが行を照合する仕組み
- JOINにおけるONとWHEREの違い
- JOINのファンアウトと行の増加
- 3つ以上のテーブルをJOINする