はじめてのSQL（文法編）

未来電子テクノロジーでインターンをしてるYasungaといいます。
今回はSQLについて自分なりに勉強したことをまとめました。
初学者で初投稿なので誤っている点があるかもしれません。
その時はコメントなどで指摘お願いします！:bow_tone1:
#SQLとは？
SQLはStructured Query Languageの略称で**データベースを管理するための言語**です。
データベースに送る命令のことを**クエリ**といい、SQLはこのクエリを記述するための言語です。
ここでデータベースとは何か？どういう特徴があるのか？と疑問に思ったので簡単にまとめました。
##データベースとは？
データベースとは**複数のデータを表形式で保存するためのツール**です。この表のことを**テーブル**といいます。
**テーブルの縦の列のことをカラム**といい、**横の行のことをレコード**といいます。
つまりデータベースは**データを保存している場所**のことで
**カラムやレコードを指定することで特定のデータを取り出せる**特徴があるということです！
#基本の構文
```SQL:基本の形式
SELECT カラム名
FROM テーブル名
WHERE 条件;
```
上記の文について
```SELECT```：カラム名を指定してそのカラムのデータを出力します。
```FROM```：テーブル名を指定します。
SELECTやFROMは何がどこにあるかを示すものになります。
```WHERE```：SELECTやFROMで指定したデータに対して条件を指定してその結果を出力します。
```WHERE カラム名="レコード名"```と書くことでそのカラムのレコードを取得できます。
WHEREについては詳しい内容をこの後に後述します。
SQLでは***文末に```;```（セミコロン）をつける必要***があります。
これをつけないと処理の終わりがどこかわからなくなるので必ず書くようにしましょう。
以下のCountryテーブルを使って詳しくみていきます。

|id|Country|City|       
|:-:|:-:|:-:|        
|0|Japan|Tokyo|
|1|China|Beijing|
|2|Canada|Ottawa|
|3|Spain|Madrid|
このテーブルからidカラムだけのデータをとり出すには
```SELECT id
   FROM Country;```
とするとidカラムの0,1,2,3のデータを取ることができます。
idの２のレコードを取ってくるには
```SELECT *
FROM Country
WHERE id = 2;```
とすればidが２のレコードを全て(Canada,Ottawa）を取得することができます。
ここでSELECTで**＊**を指定していますがこれは**全てのカラム**を意味しています。
これは頻繁に使うので覚えておいたほうがいいです。
#複雑な処理の実装　
##WHEREの詳細な使い方
- ***比較演算子***
比較演算子(>, <, >=, <=)を用いることができます。比較演算子はデータの型によって処理が変化します。
***数値データ***：数字の大小を比較してデータを出力
***日付データ***：日付以前、または以降のデータを出力

- ***データ検索***
```WHERE カラム名 LIKE "検索したい文字列"```
このように書くことで指定した文字列を含むデータを取得してきます。
検索したい文字列の前後に```%```を書くことで前後の文字列を含んでデータを所得します。
この```%```を***ワイルドカード***といいどんな文字列にも一致する記号を表しています。

- ***NULLとNOT***
WHEREは通常NULLのデータを取得できません。
NULLも含むデータを取得したいときは```WHERE カラム名 IS NULL```
ISの後ろに```NOT```をつけることでNULL以外のデータを所得できます。
NOTは指定したデータ以外を取得することができるのでWHEREやLIKEの後にも書くことがきます。
##集計関数
集計関数は指定したカラムに対して様々な計算をする関数のことで、全てSELECTの後に書きます。
```SUM(カラム名)```：カラムの合計を計算します。
```AVG(カラム名)```：カラムの平均を計算します。
```COUNT(カラム名)```：カラムの数を数えます。
```MAX(カラム名),MIN(カラム名)```：カラムの中の最大値、または最小値を見つけます。
##ANDやLIMITなどの便利な処理
上で説明したもの以外にも便利な処理があります。
```SELECT DISTINCT(カラム名)```：データの中で***重複したものを除いて取得***します。
```AND, OR```：WHEREの後に書き、条件をさらに絞るときに使います。
ANDの場合：ANDの条件とWHEREの条件の***２つを満たしたデータ***を取得します。
ORの場合：ORの条件とWHEREの条件の***どちらか一方を満たすデータ***を取得します。
```ORDER BY```：データをソートするときに使います。
昇順にする場合：```ORDER BY カラム名　ASC```
降順にする場合：```ORDER　BY　カラム名　DESC```
```LIMIT データ数```：表示するデータ数を制限します。
```GROUP BY```：集計したデータをグループ化します。
GROUP BYはSELECTで表示するカラムと集計関数をあらかじめ宣言する必要があります。
```HAVING```：グループ化したテーブルに対して条件を指定してデータを絞り込みます。
原則としてGROUP BYの後に書きます。
```SELECT カラム名 AS 変更したい名前```：実行結果のカラム名を変更することができます。

##サブクエリ
サブクエリはより複雑なデータを取得して条件を宣言するときに使われます。
サブクエリは()の中に記述することができます。基本的な書き方はクエリと同じです。

```sql:サブクエリ
SELECT カラム１
FROM テーブル
WHERE カラム１ > (
 SELECT カラム２
 FROM テーブル
);
```
上記では同じテーブルのカラム１とカラム２の値についてカラム2より大きい値を取得します。
#テーブル操作
##JOINとON
```sql:内部結合
JOIN 結合したいテーブル
ON 結合条件
```
２つのテーブルはJOINとONを用いることで結合することができます。
***JOINについて***
JOINで指定した場合、***結合条件とマッチしなかったデータは削除されてしまいます。
この特性を持つ結合方法を内部結合***といいます。
##LEFT JOINとRIGHT JOIN
```LEFT JOIN```：左側のテーブル（FROMで指定したテーブル）を軸にして結合
```RIGHT JOIN```：右側のテーブル（RIGHT JOINで指定したテーブル）を軸にして結合
このとき上記のJOINとの違いは***結合条件が違ってもデータを取得してくる点です。
これを外部結合***といいます。
外部結合の場合、***軸にしたレコードと一致しない時は値がNULLの要素を生成して結合***します。

内部結合と外部結合についてもっと知りたいという方は以下の記事でより詳しく解説されています。
[【INNER JOIN, LEFT JOIN , RIGHT JOIN】テーブル結合の挙動をまとめてみた【SQL】](https://qiita.com/ngron/items/db4947fb0551f21321c0)

#データの追加・更新・削除
##データの追加
```sql:データ挿入
INSERT INTO テーブル名（カラム名）
VALUES(挿入する値)
```
これによってテーブルにデータを挿入することができます。カラム名は複数指定できます。
また挿入する値とカラムのデータ型は同じにする必要があります。
##データの更新・削除
```sql:データ更新
UPDATE テーブル名
SET カラム名=値
WHERE 条件
```

```sql:データ削除
DELETE FROM テーブル名
WHERE 条件
```
データの更新、削除をする場合、必ずWHEREで条件を指定する必要があります。
これをしないと更新の場合はテーブル全てのデータが上書きされ
削除の場合はテーブルごと削除されてしまいます。
#まとめ
基本的なことを簡単にまとめるつもりが結構長くなってしまいました。
ProgateやHackerRankで勉強したので曖昧な部分が多く書いているときは調べながらやっていました。特にテーブルの結合が理解に時間がかかりました。次は自分の環境を作ってデータベースをいじりながら覚えていきたいです。