【SQL】基本的な命令文の使い方一覧

# はじめに
SQLについて勉強したので復習も兼ねて簡単にまとめておきます
今回はSQLの命令文の使い方一覧を簡単にまとめました
MySQLやPostgreSQLなどDB製品ごとに多少の書き方の違いはあるかもしれませんが、大枠は同じはずです

# SQLを学ぶ意義
SQLを学ぶメリットについて調べたところ色々な情報が得られましたが、以下が主な理由かと思います

- ほぼ全てのwebアプリケーションでDBが使われている
- DB製品ごとに使い方に大差がない
- 変化が少ないためずっと使えるスキル
- 言語やフレームワークごとにメソッドは変わるが、裏で動いてるDBの操作は共通


# SQL命令の種類
全てのSQL文は以下の4種類の命令に分類することができます

- データを操作する立場
 - DML: データ操作言語
 - TCL: トランザクション制御言語
- データベースを操作する立場
 - DDL: データ定義言語
 - DCL: データ制御言語


## 1. DML(Data Manipulation Language)
データ操作言語: データの格納や取り出し、更新、削除などの命令を行う

今回は4大命令と言われているよく使う以下の命令のみ取りあげます

 - SELECT
 - UPDATE
 - DELETE
 - INSERT

<img width="540" alt="スクリーンショット 2020-02-20 12.44.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/444a907d-ed0b-5a48-9e26-ad2e97e70701.png">

実例があった方がわかりやすいと思うので、この先以下の家計簿というテーブルに対してSQL文を実行していきます

**家計簿テーブル**
<img width="400" alt="スクリーンショット 2020-02-18 19.59.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/a3f33402-efac-fbde-d209-7b1e1fa4e228.png">

### SELECT
最も頻繁に使われる。
特定のテーブルから条件を指定して目的のデータを取得する命令
以下の例では、家計簿テーブルから品目が公共料金であるレコードを絞り込み、
そのレコードのidと内容と品目と出金額を出金額の降順に取得したものです

```SQL
SELECT id, 内容, 品目, 出金額   #列名 "*"とすると全ての列が対象になる
FROM 家計簿                    #テーブル名
WHERE 品目 = "公共料金"         #行の絞り込み
ORDER BY 出金額 DESC           #降順に並び替え(デフォルトは昇順 ASC)

```

<img width="760" alt="スクリーンショット 2020-02-20 18.50.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/989636ff-c7a2-4281-8d22-40f5bed4ee21.png">


SELECTには検索結果を加工するための様々なオプションがあります
全部紹介すると長くなってしまうので、今回は基本的なものの紹介に留めます
GROUP BYやHAVINGなどの使い方は別で記事にしようと思います

### UPDATE
テーブルに存在するデータを書き換えるための命令
以下の例では、家計簿テーブルの内容が誕生日会であるレコードに対して、その出金額を6000にするよう更新しています
そのため内容が誕生日会であるレコードが他にもあるとそちらも更新されるので注意です
このとき**WHEREを書き忘れると全ての行が更新されてしまうので必ずWHEREを書きましょう**

```SQL
UPDATE 家計簿           #変更したいテーブル名
SET 出金額 = 6000       #変更する列名と変更内容
WHERE 内容 = '誕生日会'  #変更する行の絞り込み
```

<img width="760" alt="スクリーンショット 2020-02-20 18.51.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/77b78b13-c6bb-034e-8c50-d874e24abeef.png">



### DELETE
テーブルに存在するデータを削除するための命令
以下の例では、家計簿テーブルの内容が誕生日会であるレコードを削除しています
DELETEではレコードごと削除するので特定の列の指定は行いません
DELETEでもUPDATEと同様、**WHEREを書かないと全ての行が削除されてしまうので必ずWHEREを書きましょう**

```SQL
DELETE FROM 家計簿      #削除する対象のあるテーブル名
WHERE 内容 = '誕生日会'  #削除する行の絞り込み
```

<img width="760" alt="スクリーンショット 2020-02-20 18.51.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/1de64c67-423e-7dee-5ba6-d5957824208f.png">


### INSERT
テーブルに新しいデータを追加するための命令
そのため、WHEREで行を絞り込む仕組みはない
以下の例では、家計簿テーブルに対して内容が携帯料金、品目が通信費、出金額が4000、日付が2020-02-25であるレコードを追加しています
(idが8になっているのは先ほどid=7のレコードをDELETEしてあり、その続きだからです)

```SQL
INSERT INTO 家計簿(内容, 品目, 出金額, 日付)         #追加するテーブル名(列名)
VALUES ('携帯料金', '通信費', 4000, '2020-02-25')  #追加する値
```

<img width="760" alt="スクリーンショット 2020-02-20 18.51.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543133/f7a980c2-c5d8-c158-62e1-a6d90476a35a.png">


## 2. TCL(Transaction Control Language)
トランザクション制御言語: トランザクションの開始や終了の命令を行う

トランザクションの詳細な説明については以下の記事を参照してください
簡単にいうと、「複数の処理の実行が全て終わって初めて、それまでの処理を全て確定させる。処理の途中でエラーになった場合は、それまでの処理を全てなかったことにする」という0か1かの世界です(原子性と言います)
この時の確定させる行為をコミット(commit)と言い、なかったことにする行為をロールバック(rollback)と言います
https://qiita.com/zd6ir7/items/6568b6c3efc5d6a13865


書き方は以下の通りで、BEGINからCOMMITまでが1つのトランザクションになります
以下の例では、AさんがBさんに5000円口座振り込みしたことを想定しています

```SQL
BEGIN;
--処理1: Aさんの口座から5000円出金
UPDATE 口座
SET 口座残高 = 口座残高 - 5000        #5000円出金
WHERE 口座番号 = [Aさんの口座番号];    
--処理2: Bさんの口座へ5000円入金
UPDATE 口座
SET 口座残高 = 口座残高 + 5000
WHERE 口座番号 = [Bさんの口座番号];     #5000円入金
COMMIT;
```

処理1の直後にエラーが発生した場合は、自動的にロールバックが行われ、処理1がなかったことになります
これがもしトランザクションではなかった場合、処理1の直後にエラーが発生すると、Aさんの口座の金額が5000円減って、Bさんの口座の金額が変わらないという悲しい世界になってしまいます。。。

平和な世界のためにもトランザクションは重要ですね


## 3. DDL(Data Definition Language)
データ定義言語: テーブルなどの作成や削除、各種設定などの命令を行う

 - CREATE
 - ALTER
 - DROP
 - TRUNCATE

### CREATE
テーブルを作成するための命令
作成したいテーブルの名前、テーブルを構成する列と型を定義する
オプションでNULL制約やデフォルト値などを設定することも可能

```SQL
CREATE TABLE 家計簿 (    #テーブル名
  内容     STRING  NOT NULL,          #列名, 型, NULL制約
  品目     STRING  DEFAULT '交際費',   #列名, 型, デフォルト値
  入金額   INTEGER,
  出金額   INTEGER,
  日付     DATE
)
```

### ALTER
テーブル定義の内容を変更するための命令
変更内容については色々ありますが、今回は列の追加と削除のみ取りあげます

```SQL
--列の追加
ALTER TABLE 家計簿 ADD 関連する人 STRING;
--列の削除
ALTER TABLE 家計簿 DROP 関連する人;
```

### DROP
テーブルそのものを削除するための命令
＊ 1. DMLで紹介したDELETE FROMではテーブルの中身しか削除できない

```SQL
DROP TABLE 家計簿
```

### TRUNCATE
テーブルを初期化するための命令
実行結果はDELETE FROM 家計簿とほぼ同じだが以下のような違いがある

- DELETEは記録を残しながら仮削除するためロールバックできるが、TRUNCATEはロールバックできない
- DELETEは低速だが、TRUNCATEは高速

```SQL
TRUNCATE TABLE 家計簿
```


## 4. DCL(Data Control Language)
データ制御言語: DMLやDDLの利用に関する許可や禁止を設定する命令を行う

データベース管理者の立場の人だけが使う命令

```SQL
--権限付与
GRANT 権限名 TO ユーザー名
--権限剥奪
REVOKE 権限名 TO ユーザー名
```


# おわりに
今回はSQLの基本的な命令文を紹介しました

ここで紹介したのは基本的な操作ですが、副問合せや結合などを使うと複数のテーブルをまたいでの処理などの複雑な処理もできるようになります
また、特定の列の値ごとにグループ化して検索したりなんかもできます

この辺は別の機会にまとめてみたいと思います

間違いなどありましたら指摘していただけると嬉しいです

# 参考書籍
スッキリわかるSQL入門 第2版 ドリル222問付き! (スッキリシリーズ) https://www.amazon.co.jp/dp/4295005096/ref=cm_sw_r_cp_api_i_osHtEbBMJ9368