SQLことはじめ

はじめに
---

SQLの概要についてまとめています。

SQLを使いこなせるようになることで、
・適切にデータを処理できる
・NoSQLとの違いを、しっかり理解する糸口になる

など、良いことが沢山あります。

SQLを学び始めの方や、これから学ぶ方のお役に立てれば嬉しいです。

SQLとは
---
`データベースを操作する言語`のことです。

`データベース`とは様々なデータを保存したものです。
データベースの保存の仕方にも色々あり、
`階層型`や`ネットワーク型`、`リレーショナル型`があります。

現在広く普及しているのは、リレーショナル型のデータベース(`RDB`: Relational DataBase)です。

`RDB`は、複数の表の形式でデータを管理しています。

以下のような感じです。

__coffee_rankingテーブル__

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 3556638 |
| 2 | ベトナム | 1616307 |
| 3 | インドネシア | 722461 |
| 4 | コロンビア | 720634 |
| 5 | ホンジュラス | 481053 |

この記事ではこのテーブルを使って解説していきます。
テーブルの中身は、2018年のコーヒー生産量の統計より、
上位５ヵ国の生産量を表しています。
>coffee_rankingテーブル
生産量順位　　(ranking)
　　　国名　　(country)
生産量[ton]　　(production)

参考資料 : [国際コーヒー機関-貿易統計表](http://www.ico.org/trade_statistics.asp?section=Statistics) 

一つの表を`テーブル`と呼び、縦の列を`カラム`、横の行を`レコード`と読んだりします。


そして、データベースのデータを操作するには、
データベースを管理するシステムが必要になります。

それが`DBMS`(DataBase Management System)です。
SQLによってデータを操作するときは、
直接データベースファイルにSQLを送るのではなく、DBMSに送られています。
そして、データを参照したいときも、DBMSがデータを持ってきてくれます。

温泉とかによくある自販機で例えると、
飲み物の番号を指定したら、中のアームが動いてコーヒー牛乳落としてくれるやつ、あのアームがDBMSです。

また、少し余談にはなりますが、
様々な言語のフレームワークでデータベースにアクセスするときも、SQLを使っています。
Ruby on Railsでは、ActiveRecordを利用してSQLを発行しています。
フレームワークに沿ったデータ取得の記述をするメリットとして、
・SQLインジェクションなどセキュリティ対策がしやすい傾向がある
・生のSQLを書く手間が省ける
などがあります。

参考資料 : [Active Record クエリインターフェイス - Railsガイド](https://railsguides.jp/active_record_querying.html#sql%E3%81%A7%E6%A4%9C%E7%B4%A2%E3%81%99%E3%82%8B) 

　
DBMSの中でも、データをリレーション型で扱うものが`RDBMS`です。

Oracle DatabaseやSQL Serverの他に、
MySQLやPostgreSQLなど、OSS（オープンソースソフトウェア）で無償で公開されているものもあります。

製品によって、SQLの命令や記述方法に違いはありますが、
基本的な部分は同じです。



続いて、基本の４大命令を解説します。


基本の４大命令
---

データの操作は４つに分類されます。
### SELECT
`一覧表示`や`検索`に使われます。
データを読み取るのみで、書き込みはしません。
Twitterで例えると、TLを眺めたりキーワード検索したりみたいな感じです。

このcoffee_rankingテーブルを使ってきます。

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 3556638 |
| 2 | ベトナム | 1616307 |
| 3 | インドネシア | 722461 |
| 4 | コロンビア | 720634 |
| 5 | ホンジュラス | 481053 |

　
下のSQLを発行すると、データベースに保存されているものが、そのまま`一覧表示として出力`できます。

```SQL
SELECT 'ranking', 'country', 'production'
  FROM coffee_ranking
```
　
実行結果

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 3556638 |
| 2 | ベトナム | 1616307 |
| 3 | インドネシア | 722461 |
| 4 | コロンビア | 720634 |
| 5 | ホンジュラス | 481053 |

`FROM`にはテーブル名を、`SELECT`には表示させたいカラム名を指定します。

また、
下記のSQLでも、先ほどと同じ出力が得られます。

```SQL
SELECT *
  FROM coffee_ranking
```

`*`はワイルドカードといい、全列検索を行えます。

ワイルドカードも用いることで記述をスッキリさせることができますが、
データベース設計変更の際に、バグの要因となることもあります。
用途によって使い分けることが必要になります。



### INSERT
新しく`データを追加`できます。
Twitterで例えると、ツイートですね。


```SQL
INSERT INTO coffee_ranking
            (ranking, country, production)
     VALUES (6, エチオピア, 470221)
```

データ型も一致させて挿入します。

実行結果

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 3556638 |
| 2 | ベトナム | 1616307 |
| 3 | インドネシア | 722461 |
| 4 | コロンビア | 720634 |
| 5 | ホンジュラス | 481053 |
| ６ | エチオピア | 470221 |



　
### UPDATE
一度登録した`データを更新`します。
Twitterで例えると、プロフィールを更新するみたいな感じです。

```SQL
UPDATE coffee_ranking
   SET production = 2000000
 WHERE country = 'ベトナム'
```

　
実行結果

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 3556638 |
| 2 | ベトナム | 2000000 |
| 3 | インドネシア | 722461 |
| 4 | コロンビア | 720634 |
| 5 | ホンジュラス | 481053 |
| ６ | エチオピア | 470221 |

　
:warning:注意点として、どのレコードを更新するか指定しないと`全部更新してしまいます`。やばいですね。

```SQL
UPDATE coffee_ranking
   SET production = 2000000
```

　
実行結果

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 2000000 |
| 2 | ベトナム | 2000000 |
| 3 | インドネシア | 2000000 |
| 4 | コロンビア | 2000000 |
| 5 | ホンジュラス | 2000000 |
| ６ | エチオピア | 2000000 |

　
### DELETE
`データを削除`できます。
Twitterで例えると、ツイ消しみたいな感じです。

上の出力結果に対して実行すると、

```SQL
DELETE FROM coffee_ranking
 WHERE country = 'エチオピア'
```

　
実行結果

| ranking | country | production|
| --- | --- | --- |
| 1 | ブラジル | 2000000 |
| 2 | ベトナム | 2000000 |
| 3 | インドネシア | 2000000 |
| 4 | コロンビア | 2000000 |
| 5 | ホンジュラス | 2000000 |

エチオピアに関するレコードが削除されました。



:warning:これを指定無しで実行すると、`テーブル内全てのレコードが消えます`。やばいですね。

```SQL
DELETE FROM coffee_ranking
```

　
実行結果


| ranking | country | production|
| --- | --- | --- |
| | |  |



SQLの基本ルール
---
### 改行
文の途中に改行を入れることができます。
例えば次の２つのSQLは同じ意味を持ちます。

```SQL
UPDATE coffee_ranking
   SET production = 2000000
 WHERE country = 'ベトナム'

UPDATE coffee_ranking   SET production = 2000000   WHERE country = 'ベトナム'
```


### 複数行の実行
複数のSQL文を実行するときは、`；`(セミコロン)で行の終了を表します。

```SQL
SELECT * FROM coffee_ranking;
INSERT INTO coffee_ranking
            (ranking, country, production)
     VALUES (7, 'ペルー', 369622);
```


### コメントアウト

```SQL
/* コメントアウトだよ */
SELECT * FROM coffee_ranking;
```

 
### 予約語
SQLの予約語はカラム名には使えません。
予約語は、DBMS製品によって異なります。


### データ型
列ごとにデータの型を決める必要があります。(以下一例)
数値　(INTEGER, DECIMAL)
文字列(VARCHAR, CHAR)
日時 （DATETIME, DATE)


よく使用される構成句
---

### WHERE句
`条件式を満たすものに絞り込む`ことができます。
SELECT,UPDATE,DELETEと併用します。

### HAVING句
条件を絞り込む点では、WHERE句と同一です。
HAVING句はGROUP BY句と一緒に用いられます。
WHERE句とHAVING句は、実行順序が異なります。
WHERE句 → GROUP BY句 → HAVING句
の順で実行されます。
`GROUP BY句の後に条件を絞りたい場合`に、HAVING句は使用されます。


### ORDER BY句
`検索結果`を並び替えます。
並び替えの種類には、`昇順(ASC)`と`降順(DESC)`があります。
Twitterのタイムラインは降順(DESC)ですね。


検索結果の加工
---
最後に検索結果を加工するものを紹介します。

### 構成句

| 句名 | 処理 |
| --- | --- |
| DISTINCT | 重複したデータを除外してくれる |
| OFFSET | 先頭から除外したい行数を選べる |
| FETCH | 取得したい行数を選べる |


 
### 集合演算子
複数のテーブルのデータを組み合わせることができます。

| 演算子名 | 処理 |
| --- | --- |
| UNION | (A ∪ B)足し合わせて取得 |
| EXCEPT | (A \ B)片方から差し引いて取得 |
| INTERSECT | (A ∩ B)重複するもののみ取得 |


### 関数
引数に対して処理を行い、戻り値を返します。
関数を使うことで、四則演算より高度で複雑な処理ができます。

| 関数名 | 処理 |
| --- | --- |
| LENGTH | 文字列もしくは数値の桁数を返す |
| REPLACE | 文字の一部を置換する |
| SUBSTRING | 文字の一部を抽出する |
| CONCAT | 文字列を連結する |
| ROUND | 四捨五入 |
| TRUNC | 切り捨て |
| POWER | べき乗 |
| AVG | 平均を求める |
| CURRENT_DATE | 現在の日付を得る |
| CAST | データ型を変換する |
| COALESCE | 最初に登場するNULLではない値を返す |


### 副問い合わせ(サブクエリ)
SQL単文よりも高度な処理が可能になります。
SELECT文の中にSELECT文を設置して、処理を実現します。

```SQL
/* 生産量が平均以上のデータを一覧出力する */
SELECT * FROM coffee_ranking
WHERE production > ( SELECT AVG(production) FROM coffee_ranking )
```

　
最後までお付き合いいただきありがとうございました！:smile: