SELF JOINは、テーブルを自分自身と結合するやり方だよ。最初は「なんで自分自身と結合するの?」って思うかもしれないけど、実際にはこういうケース結構あるんだ。例えば、社員テーブルがあって、各社員にはマネージャーがいるとする。マネージャーも社員だから、同じテーブルにデータが入ってるよね。SELF JOINを使えば、社員とそのマネージャーを紐付けられるんだ。
フォーマルに言うと、SELF JOINは普通のJOINだけど、同じテーブルを2回使って、それぞれに別のエイリアス(別名)をつけて区別するって感じ。
SELF JOINはこんな時に使えるよ:
- 階層的な関係: 「親-子」みたいな関係を作るとき。例えば社員とそのマネージャー。
- テーブル内データの分析: テーブル内のレコード同士を比較したいとき。例えば似てる商品やイベントを探すとき。
- ロジックが重複するような複雑なクエリ。
SELF JOINのシンタックス
分かりやすくするために、SELF JOINのシンプルな書き方を見てみよう:
SELECT
A.column_name,
B.column_name
FROM
table_name A
JOIN
table_name B
ON
A.common_column = B.common_column;
ここで:
table_name Aとtable_name Bは同じテーブルだけど、エイリアスが違うだけ。A.common_columnとB.common_columnは、レコードを結合するために使うカラム。
エイリアス(AとB)がないと、DBMSがどっちの「コピー」を使ってるか分からなくなるから必要なんだ。
SELF JOINの使い方例
例1: 社員とそのマネージャーのリスト
例えば、こんなemployeesテーブルがあるとする:
| employee_id | name | manager_id |
|---|---|---|
| 1 | Alex Lin | NULL |
| 2 | Maria Chi | 1 |
| 3 | Otto Song | 1 |
| 4 | Nina Zhao | 2 |
このテーブルでは:
employee_id— 社員のID。name— 社員の名前。manager_id— マネージャーのIDで、他の社員のemployee_idでもある。
やりたいこと: 社員とそのマネージャーのリストを取得する。
この課題はSELF JOINでこうやって解決できるよ:
SELECT
e.name AS employee_name,
m.name AS manager_name
FROM
employees e
LEFT JOIN
employees m
ON
e.manager_id = m.employee_id;
結果:
| employee_name | manager_name |
|---|---|
| Alex Lin | NULL |
| Maria Chi | Alex Lin |
| Otto Song | Alex Lin |
| Nina Zhao | Maria Chi |
ここで:
- テーブル
eは「社員」。 - テーブル
mも「社員」だけど、「マネージャー」として使ってる。
Alex Linはマネージャーがいない(manager_id = NULL)から、結果のmanager_nameは空になるよ。
例2: 似ている商品の検索
例えば、productsテーブルがあるとする:
| product_id | product_name | category |
|---|---|---|
| 1 | 冷蔵庫 | テクニカ |
| 2 | 洗濯機 | テクニカ |
| 3 | スマートフォン | ガジェット |
| 4 | タブレット | ガジェット |
やりたいこと: 同じカテゴリの商品ペアを探す。
SELF JOINを使った解決方法:
SELECT
p1.product_name AS product_1,
p2.product_name AS product_2
FROM
products p1
JOIN
products p2
ON
p1.category = p2.category
AND
p1.product_id < p2.product_id;
結果:
| product_1 | product_2 |
|---|---|
| 冷蔵庫 | 洗濯機 |
| スマートフォン | タブレット |
p1.product_id < p2.product_idの条件に注目してね。これでペアの重複(例えば冷蔵庫 — 洗濯機と洗濯機 — 冷蔵庫の両方)が出ないようにしてるよ。
例3: 階層分析(親と子)
もう一つ例を見てみよう。categoriesテーブルがあるとする:
| category_id | category_name | parent_id |
|---|---|---|
| 1 | テクニカ | NULL |
| 2 | ガジェット | 1 |
| 3 | コンピュータ | 1 |
| 4 | スマートフォン | 2 |
ここでは:
category_id— カテゴリのID。category_name— カテゴリ名。parent_id— 親カテゴリのID。
やりたいこと: カテゴリとその親カテゴリを紐付ける。
クエリ:
SELECT
c1.category_name AS child_category,
c2.category_name AS parent_category
FROM
categories c1
LEFT JOIN
categories c2
ON
c1.parent_id = c2.category_id;
結果:
| child_category | parent_category |
|---|---|
| テクニカ | NULL |
| ガジェット | テクニカ |
| コンピュータ | テクニカ |
| スマートフォン | ガジェット |
SELF JOINでよくあるミス
エイリアス(別名)を付け忘れる: エイリアスを使わないと、どっちの「コピー」か区別できなくなるよ。
循環参照: データに循環参照(例えば社員が自分自身のマネージャー)があると、予想外の結果になることがある。
結果の重複: 結果をフィルタ(例えばp1.product_id < p2.product_id)しないと、重複が出るから注意!
SELF JOINはデータ操作でめっちゃ便利なツールだし、正しく使えば階層やテーブル内の関係、データ分析もバッチリできるよ。これでSQLの「セルフィー」の便利さが分かったでしょ!
GO TO FULL VERSION