【SQL】一筋縄ではいかないデータ取得をサブクエリで解決する

# はじめに
SQLでデータを抽出する際に、そんなに難しくなさそうだけどどうやるんだっけ？となるときありませんか？

**「Aさんの部署と一致する人のデータがほしいけど、"WHERE name = 'A'"にするとAさんの情報しか取得できないし、正確な部署名がわからないから"WHERE busyo = "で検索できない。。」**

**「部署名が一致するデータを取得したいけど、使用するテーブルに部署名の情報ないんだよなあ。。」**

今回は、上記の抽出が叶うクエリをご紹介します:information_desk_person_tone1:

# 使用するクエリ
このようなときは、"<font color="Red">**サブクエリ（副問合せ）**</font>"を使用します。
サブクエリは、"**SQL文の中に入れ子でSQL文を記述する**"方法です。

### **例①：該当者の部署と一致する人のデータがほしい**
▼ 前提となるemployeeテーブル情報
| id       | name    | busyo     |
|:--------:|:-------:|:---------:|
| 1        | A       | 開発部    |
| 2        | B       | 営業部    |
| 3        | C       | 管理部    |
| 4        | D       | 開発部    |
| 5        | E       | 営業部    |
| 6        | F       | 管理部    |
| 7        | G       | 開発部    |
| 8        | H       | 営業部    |
| 9        | I       | 管理部    |
| 10       | J       | 開発部    |
| 11       | K       | 営業部    |
| 12       | L       | 管理部    |
| 13       | M       | 開発部    |
| 14       | N       | 営業部    |
| 15       | O       | 管理部    |

Aさんと同じ部署（開発部）に所属している人を取得する場合は、以下で取得可能です。

```sql
SELECT * FROM crane.employee
WHERE busyo =
	(SELECT busyo FROM crane.employee
	 WHERE name = 'A')
```

▼ 実行結果
| id       | name    | busyo     |
|:--------:|:-------:|:---------:|
| 1        | A       | 開発部    |
| 4        | D       | 開発部    |
| 7        | G       | 開発部    |
| 10       | J       | 開発部    |
| 13       | M       | 開発部    |

### **例②：メインテーブルに部署名情報はないが、部署名が一致するデータを取得したい**
▼ 前提となるemployee（メイン）テーブル情報
| id       | name    | busyo_cd  |
|:--------:|:-------:|:---------:|
| 1        | A       | 1         |
| 2        | B       | 2         |
| 3        | C       | 3         |
| 4        | D       | 1         |
| 5        | E       | 2         |
| 6        | F       | 3         |
| 7        | G       | 1         |
| 8        | H       | 2         |
| 9        | I       | 3         |
| 10       | J       | 1         |
| 11       | K       | 2         |
| 12       | L       | 3         |
| 13       | M       | 1         |
| 14       | N       | 2         |
| 15       | O       | 3         |

▼ 前提となるdepartment（サブ）テーブル情報
| busyo_cd | busyo_name |
|:--------:|:----------:|
| 1        | 開発部     |
| 2        | 営業部     |
| 3        | 管理部     |

営業部に所属している人を取得する場合は、以下で取得可能です。

```sql
SELECT * FROM crane.employee
WHERE busyo_cd =
    (SELECT busyo_cd FROM crane.department
     WHERE busyo_name = '営業部')
```

▼ 実行結果
| id       | name    | busyo_cd  |
|:--------:|:-------:|:---------:|
| 2        | B       | 2         |
| 5        | E       | 2         |
| 8        | H       | 2         |
| 11       | K       | 2         |
| 14       | N       | 2         |

部署名も併せて抽出したい場合は、JOIN構文を使用して結合することで実現可能です。

```sql
SELECT T.*
FROM (
 SELECT E.id, E.name, E.busyo_cd, D.busyo_name
 FROM crane.employee E
 JOIN crane.department D ON E.busyo_cd = D.busyo_cd
) T
WHERE T.busyo_name = '営業部'
```

▼ 実行結果
| id       | name    | busyo_cd  | busyo_name |
|:--------:|:-------:|:---------:|:----------:|
| 2        | B       | 2         | 営業部     |
| 5        | E       | 2         | 営業部     |
| 8        | H       | 2         | 営業部     |
| 11       | K       | 2         | 営業部     |
| 14       | N       | 2         | 営業部     |

# 最後に
今回は、ちょっぴり複雑なクエリをご紹介いたしました。
サブクエリが使いこなせるようになるとできることの幅が広がるので、今後も役立ちそうなSQL文を定期的に掲載します。

最後までお読みいただき、ありがとうございました:smiley_cat: