[SQLのはじめ方] Part13: 自己結合と多段結合

SQL

同じテーブルや複数のテーブルを自在に操る

これまでのステップでは、主に1つまたは2つのテーブルを操作する方法を学びました。このセクションでは、少し応用的なテーブル操作である「自己結合」と「多段結合」について解説します。これらをマスターすると、より複雑なデータ構造から情報を引き出すことができるようになります!💪

自己結合 (Self Join)

自己結合とは、その名の通り、同じテーブルを自分自身に結合する操作です。一見、不思議に思うかもしれませんが、テーブル内のデータ同士の関係性を調べたい場合に非常に役立ちます。

💡 どんな時に使うの?
自己結合は、主に以下のようなケースで使われます。
  • 階層構造データの取得: 例えば、従業員テーブルに「従業員ID」と「上司の従業員ID」が含まれている場合、各従業員とその上司の名前を取得できます。
  • テーブル内での比較: 同じテーブル内のレコードを比較したい場合。例えば、同じ都市に住む顧客同士を見つける、など。

自己結合の仕組み

自己結合を行うには、同じテーブルに対して異なるエイリアス(別名)を付けます。これにより、SQLはあたかも2つの異なるテーブルを扱っているかのように認識し、指定された条件で結合を行います。

例:従業員とその上司の名前を取得する

以下のような `employees` テーブルがあるとします。`manager_id` カラムには、その従業員の上司の `employee_id` が入っています。一番上の役職者など、上司がいない場合は `NULL` になります。

employee_id employee_name manager_id
1 田中 太郎 3
2 佐藤 花子 3
3 鈴木 一郎 4
4 高橋 次郎 NULL
5 伊藤 三郎 4

このテーブルから、各従業員の名前とその上司の名前を取得するには、以下のような自己結合クエリを実行します。

SELECT
    e.employee_name AS "従業員名",
    m.employee_name AS "上司名"
FROM
    employees e -- 従業員テーブルにエイリアス 'e' を付ける
LEFT JOIN
    employees m ON e.manager_id = m.employee_id; -- 上司テーブル(同じemployees)にエイリアス 'm' を付け、manager_id と employee_id で結合

解説:

  • FROM employees e で、従業員テーブルにエイリアス `e` を付けています。
  • LEFT JOIN employees m で、同じ従業員テーブルにエイリアス `m` を付けて結合しています。ここでは、上司が存在しない従業員(`manager_id` が `NULL`)も結果に含めるために `LEFT JOIN` を使用しています。
  • ON e.manager_id = m.employee_id で、従業員(`e`)の `manager_id` と、上司(`m`)の `employee_id` が一致する行を結合しています。
  • `SELECT`句で、従業員(`e`)の名前と上司(`m`)の名前を取得しています。

実行結果:

従業員名 上司名
田中 太郎 鈴木 一郎
佐藤 花子 鈴木 一郎
鈴木 一郎 高橋 次郎
高橋 次郎 NULL
伊藤 三郎 高橋 次郎

このように、自己結合を使うことで、1つのテーブル内の関係性をうまく抽出できましたね!🧑‍🤝‍🧑

多段結合 (Multi-Stage Join)

多段結合とは、3つ以上のテーブルを連続して結合する操作です。実際の業務システムでは、データが正規化され、複数のテーブルに分割されていることがよくあります。このような場合に、関連する情報をまとめて取得するために多段結合が使われます。

💡 どんな時に使うの?
正規化されたデータベースで、複数のテーブルにまたがる情報を一度に取得したい場合に利用します。例えば、「どの顧客が」「どの商品を」「いつ注文したか」を知りたい場合などです。

多段結合の仕組み

多段結合は、単純に `JOIN` 句を複数回連ねて記述することで実現できます。最初の `JOIN` で2つのテーブルを結合し、その結果に対してさらに別のテーブルを `JOIN` していくイメージです。

例:顧客の注文履歴と商品情報を取得する

以下の3つのテーブルがあるとします。

`customers` テーブル:

customer_id customer_name
101 山田 商店
102 木村 文具

`orders` テーブル:

order_id customer_id order_date
1001 101 2025-03-15
1002 102 2025-03-16
1003 101 2025-03-17

`order_details` テーブル: (`orders`テーブルと`products`テーブルの中間テーブル)

order_detail_id order_id product_id quantity
2001 1001 PN-01 10
2002 1002 NT-05 5
2003 1003 PN-02 20
2004 1003 NT-05 8

`products` テーブル:

product_id product_name price
PN-01 ボールペン (黒) 100
PN-02 ボールペン (赤) 100
NT-05 ノート B5 150

これらのテーブルから、「どの顧客が」「いつ」「どの商品を」「いくつ」注文したかを取得するには、以下のような多段結合クエリを実行します。

SELECT
    c.customer_name AS "顧客名",
    o.order_date AS "注文日",
    p.product_name AS "商品名",
    od.quantity AS "数量"
FROM
    orders o
INNER JOIN
    customers c ON o.customer_id = c.customer_id -- まず orders と customers を結合
INNER JOIN
    order_details od ON o.order_id = od.order_id -- 次に order_details を結合
INNER JOIN
    products p ON od.product_id = p.product_id; -- 最後に products を結合

解説:

  • 最初に `orders` テーブルと `customers` テーブルを `customer_id` で結合します。
  • 次に、その結合結果に対して `order_details` テーブルを `order_id` で結合します。
  • 最後に、さらにその結果に対して `products` テーブルを `product_id` で結合します。
  • これにより、4つのテーブルに分散していた情報を1つの結果セットとして取得できます。

実行結果:

顧客名 注文日 商品名 数量
山田 商店 2025-03-15 ボールペン (黒) 10
木村 文具 2025-03-16 ノート B5 5
山田 商店 2025-03-17 ボールペン (赤) 20
山田 商店 2025-03-17 ノート B5 8

このように、`JOIN` を繋げていくことで、複雑な関連を持つデータも効率的に取得できますね!📊

まとめ

  • 自己結合は、同じテーブル内でデータ間の関係性を調べたいときに使う。テーブルに異なるエイリアスを付けるのがポイント。
  • 多段結合は、3つ以上のテーブルを連続して結合する。`JOIN`句を繋げて記述する。

自己結合と多段結合は、SQLでより高度なデータ分析や情報抽出を行うための重要なテクニックです。最初は少し複雑に感じるかもしれませんが、テーブル間の関連性を意識しながら練習すれば、必ず理解できるようになります。次のステップ「副問い合わせ(サブクエリ)」では、さらにSQLの表現力を高める方法を学びます。お楽しみに!🚀

コメント

タイトルとURLをコピーしました