SQL 内部結合と外部結合

# 結合とは
SQLにおける結合とは、**データベース内の2つ以上のテーブルから関連するデータを組み合わせて新たなデータセット(テーブル)を作成する方法**です。

SQLにはいくつかの結合方法が存在しますが、今回は **内部結合(INNER JOIN)** と **外部結合(OUTER JOIN)** の二つを紹介します。

### 今回使うサンプルテーブル

1.Employeesテーブル
| EmployeeID | EmployeeName | Age | DepartmentID |
|------------|--------------|-----|--------------|
| 000A       | 加藤         | 40  | D01          |
| 000B       | 藤本         | 32  | D02          |
| 001F       | 三島         | 50  | D03          |
| 000A       | 齋藤         | 47  | D03          |
| 009F       | 田島         | 25  | D01          |
| 010A       | 渋谷         | 33  | D04          |


2.Departmentsテーブル
| DepartmentID | DepartmentName |
|------------|--------|
| D01        | 開発   |
| D02        | 人事   |
| D03        | 営業   |
| D04        | 総務   |
| D05        | 財務   |


# 内部結合 (INNER JOIN)
内部結合とは共通のキーを持つ行のみを抽出・結合し、新たなデータセットを作成する結合方法です。
つまり、データが一致しない行は除外されるので **NULLは含みません。** 

それではEmployeesテーブルとDepartmentsテーブルを内部結合してデータを取得してみます。
```SQL:内部結合 (INNER JOIN)
SELECT Employees.EmployeeID, Employees.EmployeeName, Employees.Age, 
       Employees.DepartmentID, Departments.DepartmentName
FROM Employees
INNER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
```
このクエリで取得したセットデータは下記のようになります。
| EmployeeID | EmployeeName | Age | DepartmentID | DepartmentName |
|------------|--------------|-----|--------------|----------------|
| 000A       | 加藤         | 40  | D01          | 開発           |
| 000B       | 藤本         | 32  | D02          | 人事           |
| 001F       | 三島         | 50  | D03          | 営業           |
| 000A       | 齋藤         | 47  | D03          | 営業           |
| 009F       | 田島         | 25  | D01          | 開発           |
| 010A       | 渋谷         | 33  | D04          | 総務           |

NULLは含まれていません。


# 外部結合 (OUTER JOIN)
外部結合とは、テーブルのすべての行を検索結果に含める結合方法です。
つまり、結合するテーブルのうち少なくとも1つのテーブルのデータが結合条件に一致せず欠落していても、それらの行を検索結果に含めて表示します。
そのため、外部結合には **NULLが含まれる場合もあります。** 


外部結合には **左外部結合** 、 **右外部結合** 、 **完全外部結合** の三種類がありますが、今回は内部結合との違いを説明する目的のため、 **左外部結合** でデータを取得します。

```SQL:左外部結合 (LEFT OUTER JOIN)
SELECT Employees.EmployeeID, Employees.EmployeeName, Employees.Age, 
       Employees.DepartmentID, Departments.DepartmentName
FROM Employees
LEFT OUTER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
```

このクエリで取得したセットデータは下記のようになります。

| EmployeeID | EmployeeName | Age | DepartmentID | DepartmentName |
|------------|--------------|-----|--------------|----------------|
| 000A       | 加藤         | 40  | D01          | 開発           |
| 000B       | 藤本         | 32  | D02          | 人事           |
| 001F       | 三島         | 50  | D03          | 営業           |
| 000A       | 齋藤         | 47  | D03          | 営業           |
| 009F       | 田島         | 25  | D01          | 開発           |
| 010A       | 渋谷         | 33  | D04          | 総務           |
| <font color="red">NULL</font>| <font color="red">NULL</font>| <font color="red">NULL</font> | D05| 財務|

社員のデータが欠落してNULLの場合でも財務部についての情報が表示されます。

# 内部結合と外部結合の使い分け
1.内部結合が適している場合
両方のテーブルに共通のキーがある場合、かつその共通のデータのみを取得したい時。
例：顧客と注文のテーブルを結合して、注文がある顧客の情報を取得したい時。

2.外部結合が適している場合
テーブルのすべてのデータを含め、欠落しているデータも含めて結果を取得したい時。
例：全ての顧客とその注文情報を取得するが、注文のない顧客も含めたい時。

# まとめ
結合されたテーブルが共通のキーを持たない場合や、一致しない行がある場合でもデータの損失を防ぎたい時は外部結合を使い、それ以外は内部結合を使う。