同じテーブルや複数のテーブルを自在に操る
これまでのステップでは、主に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の表現力を高める方法を学びます。お楽しみに!🚀
コメント