スッキリわかるSQL入門を読んで

# はじめに
今回は[「スッキリわかるSQL入門」](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB256%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8B%E5%85%A5%E9%96%80%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1/dp/4295013390/ref=asc_df_4295013390/?tag=jpgo-22&linkCode=df0&hvadid=553968464768&hvpos=&hvnetw=g&hvrand=3081440765317823997&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028851&hvtargid=pla-1598950080935&psc=1&th=1&psc=1)を読了したので、その感想記事を作成しました。
詳しい説明は省きますが、ここでいうSQL文とは、**「データベースに指示を出して操作するための命令文」** と考えていただければ大丈夫です。
ぜひ最後まで閲覧いただけると嬉しいです。


# 良かったところ

### 初学者でもSQLを理解しやすい構成
本書は、「SQL」を全く知らない人でも、理解できるように、解説がされています。
少々クセがあるSQLを理解しやすいように、図や漫画を用いて解説がされており、自分はサクサク読み進めることができました。

1章で「SQL」「データベース」とは何かを説明し、
2章で「SELECT、UPDATE、INSERT、DELETE」の4大命令を

:::note info
**検索系と更新系**
検索系:SELECT
更新系:UPDATE,DELETE,INSERT
:::

:::note info
**既存系と新規系**
既存系:SELECT,UPDATE,DELETE
更新系:INSERT
:::
といった形で体系化して、図を用いてわかりやすく解説してくれています。
3章以降では　where句、select文の加工、関数、副問合せ、テーブル結合、トランザクション、DB設計といった形で徐々にレベルをあげながら、解説されていく構成になっており、段階的に理解を深めていくことができます。

### 手を動かして、DBを操作する環境が最初から用意されている
実際に手を動かしてコードを書いて、それがどう動くのかを確認することで、より理解が深まるというのがプログラミングの鉄則ですよね。
SQL文でも同様に、実際に命令文を手を動かして書いて、DBから返される結果、挙動を確認することで理解を深めることができます。
ただ、上記を実行するためには

1.　データベース管理システムのインストール　(SQL Server,MySQL,PostgreSQLなど)
2.　上記システムの初期設定(管理ユーザー情報登録、Server、DB、テーブルなどの作成)
3.　SQL文の命令を実行するサンプルデータを作成し、DBへ反映

といった**環境設定**をする必要があり、この段階で特に初学者の方は挫折してしまうことが少なくありません。
一方、本書では最初から手を動かしてSQL文を書いていける環境を用意してくれています。
本書で使用する「dokoQL」というクラウドサービスは、煩雑な環境設定をする必要もなく、サンプルデータも最初から用意してくれているので、初めからSQL文を書いて、その挙動を確認することができます。
演習問題も豊富に用意されているので、どんどん手を動かしてSQL文を手に馴染ませていくことをお勧めします！

# 学んだこと

### RDB(リレーショナルデータベース)とは
* Excelシートのような複数の表が入っており、個々の表のことを``「テーブル」``と言う。
* テーブルは``行``と``列``で構成される。

### SQLとは
* データベースを操作するための専用の言語のこと
* SQL文を用いて、DBの特定の列のデータを取り出したり、書き換えたりする処理をすることが可能

### UPDATE文とDELETE文
* UPDATE文とDELETE文はWHERE句で対象の行を絞り込まないとテーブル全件に変更が適用されてしまうので注意！基本的に「WHERE句のないUPDATE文、DELETE文」は滅多にないものと意識しておく。

### WHERE句
* WHERE句に記述できるものは結果が必ず真(TRUE)または偽(FALSE)になる条件式

### 主キー
* 重複した行があると、行を区別することができず、特定の行をWHERE句で操作することができなくなる。
* 上機能ような重複を避けるために、ある1行を完全に特定できる値である``主キー``を設定する必要がある。

### 検索結果の加工
SELECT文で取得した内容は以下のように加工することができる。

| 加工内容 | SQL文 |
|:-:|:-:|
| 重複を除外  |  DISTINCT |
| 結果を並び替える  | ORDER BY  |
| 行を限定して取得する  | OFFSET - FETCH  |
| 結果を集合演算する  |  UNION,EXCEPT/MINUS,INTERSECT |

### 関数
* 呼び出し時に指定した情報(引数)に対して、定められた処理を行い、結果(戻り値)に変換する
* 関数は処理の内容や戻り値に応じて、文字列関数、算術関数、日付関数、変換関数などに分類される。

→関数は実際にSQL文を手を動かして記述していく中で覚えていく。

### 集計関数
* ``集計関数``:検索結果を集計し、１行にまとめることができる関数のこと。
* 代表的な集計関数

| 関数名 | 処理 |
|:-:|:-:|
|  SUM |  各行の値の合計を求める |
|  MAX | 各行の値の最大値を求める  |
|  MIN | 各行の値の最小値を求める  |
|  AVG | 各行の値の平均値を求める  |
|  COUNT | 行数をカウントする  |

#### 集計関数の注意点
* 集計関数はSELECT文、ORDER BY句、HAVING句でしか使用することができない。(※WHERE句の中では使用することができない)
* 結果表は必ず長方形になり、結果表が凸凹になるようなSQL文は実行できない
→下記のSQL文は結果が複数行、1行になるため実行することができない。
```
SELECT 複数行の列,集計関数(列) FROM テーブル
```

### グループ化
* ``GROUP BY``:集計に先立って、指定した基準で検索結果をいくつかのまとまりに分ける機能
* 　``HAVING``:集計処理を行った後の結果表に対して絞り込みを行いたい場合は、WHERE句ではなく、HAVING句を使う。

### 副問い合わせ
* ``副問い合わせ``:他のSQL文の一部分として登場するSELECT文。丸括弧で括って記述する。
* 副問い合わせの処理はまず内側にあるSELECT文が実行され、外側のSQL文が実行される。

| 副問い合わせの３パターン | 
|:-:|
| 単一の値の代わりとして、副問い合わせの検索結果を用いる。  |
| 複数の値の代わりとして、副問い合わせの検索結果を用いる。  |
| 表の値の代わりとして、副問い合わせの検索結果を用いる。  |

### テーブルの結合
* テーブルを複数に分けて管理することで、登録内容に重複が無くなり、仕様変更に対応しやすくなる。安全、確実にデータを管理することができる。
* 分割したテーブルを視覚的に見やすくするためにテーブルの結合を行う。
* 結合結果は結合条件が満たされた行同士をそれぞれ結ぶ
```
SELECT 選択別リスト
　　　　FROM テーブルA
　　　　JOIN テーブルB
    ON 両テーブルの結合条件（外部キーの指定）
```

#### 結合相手のない結合
* 結合相手が見つからない場合、下記のような形で結合をすることが可能(相手型がNULLでも結合することが可能)

```.左外部結合（左表の全行を完全出力する）
SELECT 〜　FROM 左表の名前
  　　　　LEFT JOIN 右表の名前
      　　　　　　　　　　ON　　結合条件
```
```.右外部結合（右表の全行を完全出力する）
SELECT 〜　FROM 左表の名前
  　　　RIGHT JOIN 右表の名前
      　　　　　　　　　　ON　　結合条件
```
```.完全外部結合（左右の全行を完全出力する）
SELECT 〜　FROM 左表の名前
  　　　 FULL JOIN 右表の名前
      　　　　　　　　　　ON　　結合条件
```
### トランザクション
* ``トランザクション``:ひとかたまりして扱われる１つ以上のSQL文のこと

#### トランザクションの制御
* トランザクションに含まれるすべてのSQL文は``「すべて完了している」``か``「１つも実行されていないか」``のどちらかの状態になるように制御する。

* ``原始性``:トランザクションに含まれるSQL文が**不可分**のものとして扱う原則のこと
* ``コミット``:トランザクションに含まれるSQL文をすべて**確定**させること
* ``ロールバック``:トランザクションに含まれるSQL文を実行中に異常が発生した場合、途中まで処理が実行されていたとしても　**「なかったこと」**　にして、処理全体をキャンセルすること

### テーブルの作成
* ``DDL(データ定義言語)``:テーブルなどの作成や削除、各種設定などの命令
* テーブル作成の基本構文
```
CREATE TABLE テーブル名 (
 列名1 列1の型名,
 列名2 列2の型名,
 :
 :
 列名X 列Xの型名
)
```
* ``DEFAULT``:insert文の項目が指定されない場合はNULLではなく、DEFAULTで設定された値を格納する

```
CREATE TABLE テーブル名 (
 列名1 型名 DEFAULT デフォルト値,
 :
 
 )
```
* ``ALTER TABLE文``:テーブルの内容を変更するために使用する構文。既存のテーブルに列を追加する場合、新しい列が挿入される位置は一番後ろになる。

```
// 列の追加
ALTER TABLE テーブル名 ADD 列名 型

// 列の削除
ALTER TABLE　　テーブル名 DROP 列名
```

### 制約
* ``制約``:テーブル作成時に各列に制約を設定し、予期しない値が格納されないようにすること。

* 基本的3つの制約↓

| 制約名 | 内容 |
|:-:|:-:|
|  NOT NULL制約 | NULLの格納を防ぐことができる  |
|  UNIQUE制約 |  重複した値の格納を防ぐことができる |
|  CHECK制約 |  格納する値が妥当かチェックできる。 |

* ``主キー制約``:テーブル作成時に主キーの列を指定。指定された列にはNULLと重複の値を入れることはできない
```
// 単独列
CREATE TABLE テーブル名 (
 列名１　型名　　　　PRIMARY KEY,
 :
)

// 複合主キー
CREATE TABLE テーブル名(
　　列名1　 型名,
　　列名2 型名,
 :
 PRIMARY KEY(列名1,列名２)
)
```
* ``参照整合制の崩壊``:外部キーで別のテーブルの行を指定しているのに、その行が存在しない状態のこと。
* ``外部キー制約``:参照整合制が崩れるようなデータ操作をしようとした場合にエラーを発生させ、強制的に処理を中断させる制約
```
CREATE TABLE テーブル名 (
  列名 型　　REFERENCES 参照先テーブル名(参照先列名)
)
```


# 難しかったこと

### 巻末ドリル(特に7章:副問合わせ、8章:テーブル結合)の問題文の抽象度が高い
巻末に「SQLドリル」という演習問題が用意されているのですが、個人的に7章:副問合せと、8章:テーブル結合の問題が高難易度に感じました。
問題文の日本語がやや抽象的で、それをSQL文に変換していくのに苦労しました。(解答を見て、「あーこの問題文はこういった形でSQL文に変換できるのかあ、、」という箇所が散見されました。)
これに関しては「ドリル」と謳っているものの、**「ITが専門ではないクライアントの要望を基に仕様書を作成し、コーディングしていく」** といったように、より実践的な演習問題だと感じました。
難易度は高いものの、これをスラスラ解けるようになれば、**「日本語↔︎SQL文」** の変換ができ、より深くSQL文を理解できている考えられます。


# 終わりに
今回は[「スッキリわかるSQL入門」](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB256%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8B%E5%85%A5%E9%96%80%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1/dp/4295013390/ref=asc_df_4295013390/?tag=jpgo-22&linkCode=df0&hvadid=553968464768&hvpos=&hvnetw=g&hvrand=3081440765317823997&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028851&hvtargid=pla-1598950080935&psc=1&th=1&psc=1)を読了しての感想記事を書かせていただきました。
データベース、SQLに関しては奥が深く、まだまだ表面的な部分しか理解できていいなので、引き続き学習を進めながら理解を深めていければと思います。
最後まで閲覧いただきありがとうございました！