SQLの基礎の基礎【新人メモ】

# はじめに
本記事では、SQLの概要から、基本的なSQL文などをまとめていきます。
会社でSQLを触ることになり、少し自分でSQL文を書いたり教えていただいたりする機会はあったが基礎からの理解はできていない、という自分のためのメモとして書いていくつもりではありますが、誰かのお役に立てると嬉しいです。

# SQLとは
SQLとは、データベースを操作するための言語です。データベースにデータを挿入したり、検索したりできます。
現在Oracle, SQLite, MySQL, PostgresSQLなど様々なデータベースがありますが、SQLは国際的に標準化されているので、基本的に同じSQLの構文を扱うことができます。

### DBの種類
メジャーに使われている2つを軽くご紹介します。
詳しくは、[MySQLユーザーがPostgreSQLを使う事になった時の比較まとめ](https://qiita.com/motsat/items/bb72af915c7bf12559f3)や、[PostgreSQLとMySQL、使うならどっち？ データベース専門家が8つの視点で徹底比較！](https://employment.en-japan.com/engineerhub/entry/2017/09/05/110000)等が参考になると思いますので、こちらをご覧ください。

- MySQL
    - 速度を重視したオープンソースのデータベースです。世界で最大級のシェアを誇り、最も人気のあるDBと言われております。無償ライセンスと有償ライセンスがあります。
- PostgresSQL
    - PostgreSQL（ポストグレスキューエル）と読み、「ポスグレ」と略されて呼ばれております。こちらもMySQLと同様、オープンソースのデータベースであり、こちらはMySQLと比べ、高機能で導入コストが低いことが特徴です。

# SQLの基本構文
基本的なSQL文は以下になります。
## データの検索
``` sql
SELECT * 
FROM テーブル名
```
「*」を指定することで、全てのカラムのデータを参照します。

``` sql
SELECT column1, column2
FROM テーブル名
```
このように、カラムを指定して検索することも可能です。

## データの挿入
``` sql
INSERT INTO テーブル名 
VALUES ('値１','値2', '値3')
```
データを追加したいテーブル名を指定し、VALUES句にそれぞれの列に対応する値を指定します。

``` sql
INSERT INTO テーブル名 (カラム1, カラム2, カラム3)
VALUES ('値１','値2', '値3')
```
カラムを明示的に記述する方法もあります。

## データの更新
``` sql
UPDATE  テーブル名
SET    レコード名 = 値 
WHERE　対象カラムの条件;
```
UPDATE句の後にテーブル名を、SET句の後に更新する列名と更新後の値を指定します。
また、更新の対象カラムをWHERE句を使って指定します。条件を指定しなければ、表の全ての行が更新されてしまうため、注意が必要です。

## データの削除
``` sql
DELETE  FROM  テーブル名
WHERE　対象カラムの条件;
```
UPDATE文とほとんどおなじ形です。
UPDATE文と同様に、条件を指定しなければ、表の全ての行が削除されてしまうため、注意が必要です。

# データの検索のオプション

### WHERE
ひとつ前の段落でも使っていますが、改めて整理します。
where句とは、SQL文の実行対象にフィルタをかけるためのものです。

``` sql
SELECT * 
FROM テーブル名
WHERE カラム名 = 値;
```
WHERE句を使うことで、あるカラム名に特定の値が入っているレコードのみ検索できます。
また、比較演算子は上記の「=」以外に以下が使用可能です。

|  比較演算子  |  意味  |
| ---- | ---- |
|  =  | 等しい |
|  <  | 左辺の方が小さい |
|  >  | 左辺の方が大きい |
|  =<  | 左辺の方が小さい、または等しい |
|  =>  | 左辺の方が大きい、または等しい |
|  !=  | 等しくない |
|  AND  | かつ |
|  OR  | または |
|  NOT  | ~でない |

### ORDER BY
ORDER BYは取り出した結果をソートします。
カラム名とASC（昇順）またはDESC（降順）を指定して使用する。
デフォルトは昇順になっており、指定なしだと昇順でソートしてくれます。

``` sql
SELECT *
FROM テーブル名
ORDER BY カラム名 DESC;
```

WHERE句との併用も可能です。

``` sql
SELECT *
FROM テーブル名
WHERE カラム名 = 値;
ORDER BY カラム名 DESC;
```

### JOIN
JOINは複数のテーブルが関連性を持っている時に使用します。
二つ以上のテーブルの値を検索したい際に便利です。

```sql
SELECT カラム名1
FROM テーブル1
INNER JOIN テーブル2
ON テーブル1.カラム名 = テーブル2.カラム名;
```
少しややこしい（と自分は思っている）ので以下に例を書いてみます。
まず、以下のような2つのテーブルがあり、idで関連づけられているものとします。

- classesテーブル

|  id | name | 
| ---- | ---- |
|  1  | apple |
|  2  | cherry |
|  3  | grape |

- studentsテーブル

|  id | name | class_id |
| ---- | ---- | ---- |
|  1  | 山本さん | 2 |
|  2  | 松田さん |1|
|  3  | 佐藤さん |4|
|  4  | 高木さん |1|

ここで、以下のSQLを実行してみます。

```sql
SELECT * 
FROM students
INNER JOIN classes 
ON students.class_id = classes.id;
```

すると、以下のような結果が取得できます。

|  id | name | classes_id | id |name|
| ---- | ---- | ----| ----| ----|
|  2  | 松田さん |1|1|cherry|
|  4  | 高木さん |1|1|cherry|
|  1  | 山本さん |2|2|apple|

studentsテーブルのid=3のレコードが表示されなくなりました。
これは、テーブルの結合時にベースとなるテーブルと結合するテーブルとの間でidが存在しないものは含まないという様になっているからである。
このようにテーブルを結合して検索することで、条件にあったレコードを複数のテーブルから検索することができます。

### 外部結合と内部結合
結合には、外部結合と内部結合の2種類あります。
上記で説明したのは内部結合（INNER JOIN）でした。
二つの違いとしては、

- 内部結合
    - それぞれのテーブルの指定したカラムの値が一致するものだけを結合
- 外部結合
    - 内部結合のようにそれぞれのテーブルの指定したカラムの値が一致するものを結合するのに加え、
    どちらかのテーブルにしか存在しないものも取得する

が挙げられます。SQLの文法は基本的にどちらも同じです。
最後に、joinの種類は以下になります。

| 結合の種類 |  名前  |  意味  |
| ---- | ---- | ---- |
|内部結合|  INNER JOIN  | テーブル1かつテーブル2のみ |
|外部結合|  FULL JOIN  | テーブル1またはテーブル2 |
|外部結合|  LEFT JOIN  | テーブル1かつテーブル2とテーブル1 |
|外部結合|  RIGHT JOIN  | テーブル1かつテーブル2とテーブル2 |