INNER JOINとOUTER JOIN【初心者向け】

SQLのJOIN構文には様々なJOINの方法があります。
使い方を定着させる為にもPostgreSQLを触りながらJOINの違いについて調べていこうと思います。

# そもそもJOIN（結合）とは
あるテーブルと違うテーブル同士を結合する集合演算の一種で、結合にはいくつかの種類があるが、大まかには<font color="red">内部結合(INNER JOIN)</font>と<font color="blue">外部結合(OUTER JOIN)</font>の2種類に分けられる。


# INNER JOIN (内部結合)
INNER JOINは内部結合と呼ばれるもので、両方のテーブルにある値だけをまとめたもの。

テーブル間の一致しないデータに関しては表示されないことに注意。

![innerjoin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/798346/e0e37802-81b2-360b-a0b3-e0fa487f0939.jpeg)
#### INNER JOINの使い方(例)
```
select * from テーブル名A inner join テーブル名B 　on テーブルAのカラム = テーブルBのカラム；
```
### 使用するテーブル
#### usersテーブル

|id  |name  |status_id  |
|---|---|---|
|1  |坂本  |2　　 |
|2  |鈴木  |1  |
|3  |山田  |4  |
|4  |高橋  |null  |

#### statusテーブル

|id  |status |
|---|---|
|1  |学生  |
|2  |エンジニア  |
|3  |経営者  |
|4  |フリーター  |

```

example-db=# select * from users inner join status on status_id = status.id;
 id | name | status_id | id |   status
----+------+-----------+----+------------
  1 | 坂本 |         2 |  2 | エンジニア
  2 | 鈴木 |         1 |  1 | 学生
  3 | 山田 |         4 |  4 | フリーター
(3 rows)
```
無事、usersテーブルのstatus.idとstatusテーブルのstatus.idが一致するデータを表示することが出来ました。
JOINを使用する際の一致条件の指定はWHERE文ではなくONで指定する事に注意が必要です！

# OUTER JOIN (外部結合)
OUTER JOINにはLEFT (OUTER) JOINとRIGHT (OUTER) JOINとFULL (OUTER) JOINがあります。※ OUTERは省略可能。

LEFT JOINはINNER JOINの一致データに加え左側のテーブルのデータも表示したもの。
RIGHT JOINはINNER JOINに加え一致データに加え右側のテーブルのデータも表示したもの。

#### OUTER JOINの使い方(例)
```
select * from テーブル名A left join テーブル名B 　on テーブルAのカラム = テーブルBのカラム；
```

![outerjoin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/798346/49779d91-f845-c520-ae05-b9b3d4ed091e.jpeg)

#### LEFT JOINした場合
```
example-db=# select * from users left join status on status_id = status.id;
 id | name | status_id | id |   status
----+------+-----------+----+------------
  1 | 坂本 |         2 |  2 | エンジニア
  2 | 鈴木 |         1 |  1 | 学生
  3 | 山田 |         4 |  4 | フリーター
  4 | 高橋 |           |    |
(4 rows)
```
テーブルのデータが一致しない高橋さんもLEFT JOINのお陰が呼ばれました。

#### RIGHT JOINした場合
```
example-db=# select * from users right join status on status_id = status.id;
 id | name | status_id | id |   status
----+------+-----------+----+------------
  2 | 鈴木 |         1 |  1 | 学生
  1 | 坂本 |         2 |  2 | エンジニア
    |      |           |  3 | 経営者
  3 | 山田 |         4 |  4 | フリーター
(4 rows)
```
RIGHT JOINにより右側のテーブルの情報の経営者が呼ばれました。

#### FULL JOINした場合
```
example-db=# select * from users full outer join status on status_id = status.id;
 id | name | status_id | id |   status
----+------+-----------+----+------------
  1 | 坂本 |         2 |  2 | エンジニア
  2 | 鈴木 |         1 |  1 | 学生
  3 | 山田 |         4 |  4 | フリーター
  4 | 高橋 |           |    |
    |      |           |  3 | 経営者
(5 rows)
```
一致しない部分も全部呼ばれました。あんまり使う機会はなさそう。

# 小ネタと感想
この記事ではテーブル名を小文字で作成しましたが、テーブル名を大文字で作成した際に""(ダブルクォーテーション)で囲わないとSQL文が識別されないという現象が発生しました。
PostgreSQLでは慣習的には大文字はキーワード、小文字は識別子で分けられるが、SQL文実行時には最終的に全て小文字で読み取られる仕組みらしいです。
その為、テーブル名に大文字を用いる場合には明示的にダブルクォーテーションで囲まないとSQL上では小文字で認識されて「そんなテーブルねーよ！」と怒られてしまいます。

結論、テーブル名は無難に小文字の方がややこしさがなく良さげですね。

JOIN構文は頭の中が訳分からなくなりがちですが、実際に手を動かしてみると少し理解度が深まった様な気がします。

「Qiitaの記事やWebサイトを見ても全然分からないや」という方は実際に一度SQL触ってみてはいかがでしょうか！

# 参照
https://www.dbonline.jp/mysql/join/index1.html
https://sql55.com/t-sql/t-sql-join-1.php
https://medium-company.com/%E5%86%85%E9%83%A8%E7%B5%90%E5%90%88-%E5%A4%96%E9%83%A8%E7%B5%90%E5%90%88-%E9%81%95%E3%81%84/
https://www.postgresql.jp/document/8.4/html/sql-syntax-lexical.html#AEN1230