MYSQL SELECT文の基本

# SELECT文
* SELECT句
* FROM句
テーブルに格納されているデータを取得するには、SELECT句とFROM句を用います。
SELECTの後ろに取得したいデータのカラム名、
FROMの後ろに取得したいデータのテーブル名を指定します。
テーブルのデータすべてを取得するにはSELECTの後ろに * を用います。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |

```SQL:テーブルのすべてのデータの取得
SELECT *
FROM sample;
```
```SQL:テーブルの一部のデータの取得（s_nameカラムとscoreカラムを取得）
SELECT s_name, score
FROM sample;
```
## ORDER BY句
取得するデータの並びを変えたいときには、ORDER BY句を用います。
昇順で取得したいときはASCを用い、降順で取得したいときはDESCを用います。
指定をしなかった場合は昇順になります。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |

```SQL:昇順で取得（scoreカラムで昇順に並び替え）
SELECT *
FROM sample
ORDER BY score ASC;
```
```SQL:昇順で取得・省略ver（s_nameカラムで昇順に並び替え）
SELECT *
FROM sample
ORDER BY s_name;
```
どちらの書き方をしても昇順となります。
```SQL:降順で取得（scoreカラムで降順に並び替え）
SELECT *
FROM sample
ORDER BY score DESC;
```
## LIMIT句
取得するデータの数を絞りたいときにはLIMIT句を用います。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |

```SQL:取得数を3つに絞る
SELECT s_name
FROM sample
ORDER BY score DESC
LIMIT 3;
```
上記の場合、scoreカラムが上位3名の名前が取得されます。

## WHERE句
条件を付けてデータを取得したいときにはWHERE句を用います。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |

```SQL:scoreカラムが100のデータを取得する
SELECT *
FROM sample
WHERE score = 100;
```
```SQL:scoreカラムが80以下のデータを取得する
SELECT *
FROM sample
WHERE score <= 80;
```
### IS NULL演算子・IS NOT NULL演算子
条件にNULLの箇所を指定したいときはWHERE カラム名 = NULLと指定せずに、IS NULL演算子を用います。
同じように、条件でNULL以外の箇所を指定したい場合は、IS NOT NULL演算子を用います。

【例】
テーブル名：sample
| id | s_name | score | pass |
|:-:|:-:|:-:|:-:|
| 1 |  一郎 |  80 | pass |
| 2 |  次郎 |  50 | |
| 3 |  三郎 |  100 | pass |
| 4 |  四郎 |  80 | pass |

```SQL:passカラムがNULLのデータを取得
SELECT *
FROM sample
WHERE pass IS NULL;
```

```SQL:passカラムがNULLでないデータを取得
SELECT *
FROM sample
WHERE pass IS NOT NULL;
```
### BETWEEN演算子
カラムの値が指定した範囲のデータを取得したいときにはBETWEEN演算子を用います。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |
```SQL:scoreカラムの値が0～80のデータを取得
SELECT *
FROM sample
WHERE score BETWEEN 0 AND 80;
```
### IN演算子
カラムの値を複数指定したい場合にはIN演算子を用います。

【例】
テーブル名：sample
| id | s_name | score |
|:-:|:-:|:-:|
| 1 |  一郎 |  80 |
| 2 |  次郎 |  50 |
| 3 |  三郎 |  100 |
| 4 |  四郎 |  80 |

```SQL:idカラムが1または3の値のデータを取得
SELECT *
FROM sample
WHERE id IN (1, 3);
```
### LIKE演算子
条件を指定するときに、パターンマッチングをしたいときにはLIKE演算子を用います。
#### 前方一致検索
カラムの値が特定の文字列から始まるデータを取得したいときには前方一致検索を用います。

【例】
テーブル名：sample
| id | s_name |
|:-:|:-:|
| 1 | たろう |
| 2 | じろう |
| 3 | たいち |
| 4 | たつき |
| 5 | はやと |

```SQL:前方一致検索(s_nameカラムが"た"から始まるデータを取得)
SELECT *
FROM sample
WHERE s_name LIKE ('た%');
```
上記の場合だと「た」から始まる値が対象になります。「た」一文字の場合も含まれます。

#### 後方一致検索
カラムの値が特定の文字列から始まるデータを取得したいときには前方一致検索を用います。

【例】
テーブル名：sample
| id | s_name |
|:-:|:-:|
| 1 | たろう |
| 2 | じろう |
| 3 | たいち |
| 4 | たつき |
| 5 | はやと |

```SQL:後方一致検索(s_nameカラムが"う"で終わるデータを取得)
SELECT *
FROM sample
WHERE s_name LIKE ('%う');
```
上記の場合だと「う」で終わる値が対象になります。「う」一文字の場合も含まれます。

#### 部分検索
カラムの値に特定の値が含まれるデータを取得したいときには部分一致検索を用います。

【例】
テーブル名：sample
| id | s_name | adresss |
|:-:|:-:|:-:|
| 1 | たろう | 東京 |
| 2 | じろう | 京都 |
| 3 | たいち | 大阪 |
| 4 | たつき | 広島 |
| 5 | はやと | 東京 |

```SQL:部分検索(adressカラムに'京'が含まれるデータを取得)
SELECT *
FROM sample
WHERE adress LIKE ('%京%');
```
上記の場合だと「京」が含まれるデータが対象となります。
→（京都）（東京）（右京区）（京）

## GROUP BY句
レコードを分けてカラムごとのデータとしてグループ分けし、分割することができます。
### COUNT()
COUNT(*)を用いるとレコードがいくつあるかを取得できます。
COUNT(カラム名)を用いるとそのカラムのNULL以外の要素がいくつあるかが取得できます。

【例】
テーブル名：sample
| team | s_name | pass |
|:-:|:-:|:-:|
| 1 | たろう | pass |
| 1 | じろう | pass |
| 2 | たいち |      |
| 2 | たつき |      |
| 2 | はやと | pass |

```SQL:COUNT(*) (sampleテーブルのレコードがいくつあるかを取得する)
SELECT COUNT(*)
FROM sample;
```
```SQL:COUNT(カラム名)（teamカラムでグループ化してpassカラムの要素数を取得する）
SELECT team, COUNT(pass)
FROM sample
GROUP BY team;
```
上記の場合、「teamカラムが1のpassカラムの要素は2、
teamカラムが2のpassカラムの要素は1」といったデータの取得ができます。

### SUM()・AVG()・MIN()・MAX()
SUM(カラム名)を用いるとそのカラムの合計を取得します。
AVG(カラム名)を用いるとそのカラムの平均を取得します。
MIN(カラム名)を用いるとそのカラムの最小値を取得します。
MAX(カラム名)を用いるとそのカラムの最大値を取得します。

【例】
テーブル名：sample
| team | s_name | score |
|:-:|:-:|:-:|
| 1 | たろう | 5 |
| 1 | じろう | 5 |
| 2 | たいち | 3 |
| 2 | たつき | 2 |
| 2 | はやと | 4 |

```SQL:SUM() (scoreカラムの値の合計を求める)
SELECT SUM(score)
FROM sample;
```
```SQL:グループ化してSUM()を用いる（teamカラムでグループ化し、scoreカラムの合計を取得）
SELECT team, SUM(score)
FROM sample
GROUP BY team;
```
上記の場合、「teamカラムが1のscoreカラムの合計は10、
teamカラムが2のscoreカラムの合計は9」といったデータの取得ができます。
```SQL:AVG()  (scoreカラムの値の平均を求める)
SELECT AVG(score)
FROM sample;
```
```SQL:グループ化してAVG()を用いる（teamカラムでグループ化し、scoreカラムの平均を取得）
SELECT team, AVG(score)
FROM sample
GROUP BY team;
```
上記の場合、「teamカラムが1のscoreカラムの平均は5、
teamカラムが2のscoreカラムの合計は3」といったデータの取得ができます。

```SQL:MIN() (scoreカラムの値の最小値を求める)
SELECT MIN(score)
FROM sample;
```
```SQL:グループ化してMIN()を用いる（teamカラムでグループ化し、scoreカラムの最小値を取得）
SELECT team, MIN(score)
FROM sample
GROUP BY team;
```
上記の場合、「teamカラムが1のscoreカラムの最小値は5、
teamカラムが2のscoreカラムの最小値は2」といったデータの取得ができます。

```SQL:MAX() (scoreカラムの値の最大値を求める)
SELECT MAX(score)
FROM sample;
```
```SQL:グループ化してMAX()を用いる（teamカラムでグループ化し、scoreカラムの最大値を取得）
SELECT team, MAX(score)
FROM sample
GROUP BY team;
```
上記の場合、「teamカラムが1のscoreカラムの最大値は5、
teamカラムが2のscoreカラムの最大値は4」といったデータの取得ができます。

### HAVING句
グループ化した後に取得する値に条件を付けたいときには、WHERE句ではなく、HAVING句を用います。

【例】
テーブル名：sample
| team | s_name | score |
|:-:|:-:|:-:|
| 1 | たろう | 5 |
| 1 | じろう | 5 |
| 2 | たいち | 3 |
| 2 | たつき | 2 |
| 2 | はやと | 4 |

```SQL:HAVING句（teamカラムでグループ化し、scoreカラムの合計が10以上のデータを取得）
SELECT team, SUM(score)
FROM sample
GROUP BY team
HAVING SUM(score) >= 10;
```
上記の場合、SUM(score)が10以上であるteamが1のグループのデータのみが取得されます。

## AS句
AS句を用いるとカラムに別の名前を付けることができます。

【例】
テーブル名：sample
| team | s_name | score |
|:-:|:-:|:-:|
| 1 | たろう | 5 |
| 1 | じろう | 5 |
| 2 | たいち | 3 |
| 2 | たつき | 2 |
| 2 | はやと | 4 |

```SQL:AS句（teamカラムにチーム、SUM(score)カラムに合計得点という名前を付ける。）
SELECT team AS チーム, SUM(score) AS 合計得点
FROM sample
GROUP BY team;
```
# テーブルの結合
2つ以上のテーブルを1つのテーブルにまとめることができます。
## 内部結合

【例】
テーブル名:sample_student
| id | s_name | sex | age | club_id |
|:-:|:-:|:-:|:-:|:-:|
| 1 | はるき | 男 | 17 | 1 |
| 2 | なつみ | 女 | 17 | 1 |
| 3 | あきと | 男 | 18 | 2 |
| 4 | ふゆこ | 女 | 16 | 3 |
| 5 | ちはる | 女 | 18 | 0 |

テーブル名:sample_club
| id | club |
|:-:|:-:|
| 1 | テニス |
| 2 | サッカー |
| 3 | 美術 |
| 4 | 吹奏楽 |

上記2つのようなテーブルがあった場合、
sample_studentテーブルのclub_idカラムと
sample_clubテーブルのidカラムを対応させて、結合することができます。
```SQL:内部結合（sample_studentテーブルとsample_clubテーブルを内部結合する）
SELECT *
FROM sample_student
INNER JOIN sample_club ON sample_student.club_id = sample_club.id;
```
上記のコードを実行すると、下記のデータを取得します。
| id | s_name | sex | age | club_id | id | club |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1 | はるき | 男 | 17 | 1 | 1 | テニス |
| 2 | なつみ | 女 | 17 | 1 | 1 | テニス |
| 3 | あきと | 男 | 18 | 2 | 2 | サッカー |
| 4 | ふゆこ | 女 | 16 | 3 | 3 | 美術 |

sample_studentテーブルのclub_idにsample_clubテーブルのidが対応する形で結合することができます。
しかし、sample_clubのidに存在しないclub_idが0の値を持つ（5, ちはる, 女, 18, 0）のデータが抜けてしまいました。
内部結合ではベースとなるテーブルから条件にマッチするレコードがなかった場合に削除されてしまうため、（5, ちはる, 女, 18, 0）のデータを取得するためには外部結合を使う必要があります。
## 外部結合
### 左外部結合

```SQL:左外部結合（sample_studentテーブルとsample_clubテーブルを左外部結合する）
SELECT *
FROM sample_student
LEFT OUTER JOIN sample_club ON sample_student.club_id = sample_club.id;
```
上記のコードを実行すると、下記のデータを取得します。
| id | s_name | sex | age | club_id | id | club |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1 | はるき | 男 | 17 | 1 | 1 | テニス |
| 2 | なつみ | 女 | 17 | 1 | 1 | テニス |
| 3 | あきと | 男 | 18 | 2 | 2 | サッカー |
| 4 | ふゆこ | 女 | 16 | 3 | 3 | 美術 |
| 5 | ちはる | 女 | 18 | 0 | | |

左外部結合では左側のテーブル（FROMの後ろに指定した方）にしかないデータも取得できます。
### 右外部結合

```SQL:右外部結合（sample_studentテーブルとsample_clubテーブルを右外部結合する）
SELECT *
FROM sample_student
RIGHT OUTER JOIN sample_club ON sample_student.club_id = sample_club.id;
```
上記のコードを実行すると、下記のデータを取得します。
| id | s_name | sex | age | club_id | id | club |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 2 | なつみ | 女 | 17 | 1 | 1 | テニス |
| 1 | はるき | 男 | 17 | 1 | 1 | テニス |
| 3 | あきと | 男 | 18 | 2 | 2 | サッカー |
| 4 | ふゆこ | 女 | 16 | 3 | 3 | 美術 |
|  |  |  |  |  | 4 | 吹奏楽 |

右外部結合では右側のテーブル（RIGHT OUTER JOINの後ろに指定した方）にしかないデータも取得できます。