SQLを理解しよう！！

#SQLとは

SQL（Structured Query Language)はリレーショナルデータベース(RDB)の操作を行うための言語です。

:warning: リレーショナルデータベースとは、データを**テーブル**という
          **表形式の構造**で管理するデータベースのことです。

SQLはデータベースやテーブルに対して様々な命令を行うことができます！
<br>
<br>

##SELECT句
- データベースから、データを取得するためには**SELECT**を用います。これを用いて**どのカラムのデータを取得するか**を選びます。

```
  SELECT name   #nameはカラム名
```
```
  SELECT *  #全てのカラムを指定する
```
<br>

##FROM句
- **FROM**を用いて、**SELECT**で選んだカラムが**どのテーブルのカラムか**を指定する必要があります。

```
  SELECT name 　　#カラム名
  FROM users;　　　#テーブル名
```
<br>

##WHERE句
- 特定のデータを取得したい時には、**WHERE**を用います。

```
  SELECT *
  FROM users
  WHERE name = "山田太郎";   #nameカラムが"山田太郎"であるデータを取得する
```
<br>

##LIKE演算子
- 「ある文字を含むデータ」を取得したい場合は、**LIKE演算子**を用います。

```
  SELECT *
  FROM users
  WHERE name LIKE '%佐藤%';   #佐藤という文字を含むデータを取得する
```
<br>

##NOT演算子
- 「○○を含まないデータや「○○に一致しないデータ」のような条件でデータを取得したい場合は**NOT演算子**を用います。

```
  SELECT *
  FROM users
  WHERE NOT name LIKE "%佐藤%";  #佐藤を含まないデータを取得する
```
<br>

##AND演算子
- AND演算子を使うと、WHEREに複数の条件を指定することができます。

```
  SELECT * FROM users
  WHERE name = "佐藤"
  AND age = 20;      #どちらの条件も満たすデータを取得する
```
<br>

##OR演算子
- AND演算子と同様に、複数の条件を指定しますが、条件１または条件２のどちらかを満たすデータを検索します。

```
  SELECT *
  FROM users
  WHERE name = "佐藤"
  OR age = 20;       #どちらかの条件を満たすデータを取得する
```
<br>

##ORDER BY
- データを並べ替える時は**ORDER BY**を使用します

```
  SELECT *
  FROM users
  ORDER BY age DESC;  #ageの大きい順に並び替える
                      #WHERE文と併用もできます 
```
<br>

##LIMIT
- 何件取得するかを指定するときは、**LIMIT**を用います。

```
  SELECT *
  FROM users
  ORDER BY age DESC
  LIMIT 5;           #ageの大きい順に並び替え、上から５番目まで取得する
```
<br>

##DISTINCT
- 検索結果から重複するデータを除くときに**DISTINCT**を使用します。

```
  SELECT DISTINCT(name)
  FROM users;          #重複するデータを除いたnameカラムのデータを取得する
```
<br>

##SUM関数
- 数値の合計を計算するときには、**SUM**を用います。

```
  SELECT SUM(price)
  FROM items;      #itemsテーブルのpriceカラムの合計を計算する
```
<br>

##AVG関数
- 数値の平均を計算する場合は、**AVG**を用います。

```
  SELECT AVG(price)
  FROM items;        #itemsテーブルのpriceカラムの平均を計算する
```
<br>

##COUNT関数
- 指定したカラムのデータの合計数を計算する場合は、**COUNT**を用います。また、そのカラムが**null**になっているデータは計算されません。

```
  SELECT COUNT(*)
  FROM users
  WHERE age >= 20;

  #ageが20以上のデータの合計数を取得します
```
<br>

##MAX・MIN関数
- **MAX**を用いると、指定したカラムの最大値を取得できます。**MIN**では最小値を取得します。

```
  SELECT MAX(price)
  FROM items         #最も値段の高いitemのデータを取得
```
```
  SELECT MIN(price)
  FROM items         #最も値段の安いitemのデータを取得
```
<br>

##CONCAT関数
- **CONCAT**関数は複数の文字列を連結させることができる関数です。</li>
:warning: ただし連結させる文字列の中にnullがあった場合、結果はnullになります。

```
  SELECT CONCAT(family_name, first_name)
  FROM users;

  #苗字と名前を連結させ表示する
```
<br>

##AS句
- SELECT句でデータを取得するとき、**AS**を使うと、そのカラムに別名をつけることができます。

```
  SELECT CONCAT(family_name, first_name) AS "名前"
  FROM users;

  #苗字と名前を連結させ、カラム名を"名前"として表示する
```
<br>

##GROUP BY句
- **GROUP BY**を使用すると、指定したカラムが同じ値を持つデータを1つのグループとしてまとめることができます。

```
  SELECT user_id
  FROM shifts
  WHERE date = "2018-07-01"
  GROUP BY user_id;

  #shiftsテーブルからdateが2018-07-01のレコードを取得し、user_idが同じ値のレコードをグループ化して、そのグループ化された一覧のuser_idのみを表示する
```
<br>

##HAVING句
- **GROUP BY**でグループ化したデータを更に絞り込みたいときは**HAVING**を用います。

```
  SELECT SUM(price), purchased_at
  FROM purchases
  GROUP BY purchased_at
  HAVING SUM(price) > 2000;
  
  #日付ごとの合計金額のうち2000円を超えるデータのみを取得する
```
####WHEHEとHAVINGの違い
**WHERE**も**HAVING**と同じように抽出条件を指定するコマンドですが、呼ばれるタイミングが違うため使い分ける必要があります。

| 呼ばれるタイミング  |            コマンド|    
|:-----------------|------------------:|
| １          　　　|              FROM |
| ２         　　　 |            WHERE  |
| ３               |          GROUP BY | 
| ４               |            HAVING |     
| ５               |            SELECT |      
| ６               |          ORDER BY |     
- このためグループ化したデータから抽出条件を指定するためには**HAVING**を用いる必要があります。
<br>

##JOIN
- **JOIN**を使用すると、指定したそれぞれのテーブルの、カラムの値が一致するデータを結合することができます。

```
  FROM shifts
  JOIN users ON shifts.user_id = users.id

  #shiftsテーブルにusersテーブルを結合させます。そしてshiftsテーブルのuser_idとusersテーブルのidが一致する行を結合させます
```
<br>

##INSERT文
- データにレコードを挿入したいときには**INSERT**を用います。

```
  INSERT INTO users(name, age) VALUES("佐藤", 20);
```
<br>

##UPDATE文
- データの更新には**UPDATE**を使用します。
- WHEREで指定しないとカラム内の**全てのデータ**が更新してしまうので注意しましょう。

```
  UPDATE users SET age = 23 WHERE id = 2;

  #idが2のageカラムを23に書き換える
```
<br>

##DELETE文
- レコードを削除するときは**DELETE**を用います。
- WHEREで指定しないとテーブル内の**全レコードが削除されてしまう**ので注意しましょう。

```
  DELETE FROM users WHERE id = 2;
```
<br>

##最後に
データベースはとても大事ですが、いざ勉強しようと思っても何すれば良いのか中々難しいと思う方は自分で作った個人アプリのデータベースを使って学習するのもいいのかなと思いました！
これどうするんだっけというときにこの記事を活用して頂けたら幸いです！

<br>
> 参考
https://www.sejuku.net/blog/74757