SQL初心者が作った初心者さんのためのクエリ文早見表: よく使う操作一覧


私はSQLを一度も勉強していなかった為よく使われるであろう

クエリ文をまとめて簡単な結果を書きました。

## 今後使う場面も増えるであろうSQL理解を深めるためアウトプットしました
まず初めにSQLとは何かについて説明します。
SQLとはデータベース言語といいデーター分析を行う時に使います。
データを分析するにはデータベース(以下DB)に命令を送ります。
その命令のことを**クエリ**と言います。

これから出てくる**テーブル**と**カラム**と**レコード**についても説明します。 こちらの表を例とします。
| 商品名   | 金額   | カテゴリー | 購入者 | 購入日       |
|--------|-----|--------|--------|------------|
| おにぎり | 200 | 食品     | 山田      | 2023-04-03 |
| りんご  | 300  | 食品     | 鈴木      | 2023-04-03 |

これらを表全部の事を**テーブル**と言います。
テーブルの縦の列を**カラム**といい、横の列を**レコード**と言います。
## よく使うであろうクエリ文を紹介します。
その前にサンプルとなるテーブルを用意しました。
| 商品   | 金額   | カテゴリー | 購入者 | 購入日       |
|--------|-----|--------|--------|------------|
| おにぎり | 200 | 食品     | 田中      | 2023-04-03 |
| りんご  | 300  | 食品     | 鈴木      | 2023-04-02 |
| 洗剤    | 500  | 生活用品 | 田中   | 2023-04-03 |
| 電気ケトル | 10000 | 生活用品 | 鈴木      | 2023-04-02 |
| コーヒー豆 | 1200 | 食品     | 鈴木     | 2023-04-03 |
| タオル  | 700  | 生活用品 | 田中    | 2023-04-03 |

後々グループ化を説明しますのでわかりやすくカテゴリー、購入者、購入日は２種類にしました。
金額と商品名はTHE適当です。

- item : 商品
- price: 金額
- category: カテゴリー
- name: 購入者
- purchase_date: 購入日

# データ取得系
## SELECT
DBのカラムを取得することができる
複数のカラムを取得する場合コンマで区切る。例(カラム,カラム)
全てのカラムを選択する場合は　*　を使う。
```sql:sample.sql
SELECT item
FROM order_history
```
| 商品   |
|--------|
| おにぎり |
| りんご  |
| 洗剤    |
| 電気ケトル |
| コーヒー豆 |
| タオル  |


この場合**FROM**で注文履歴テーブルを指定し
**SELECT**で商品カラムを取得してます。
注意：今回は重複はありませんがあった場合このクエリ文だと重複します
どうすればいいのかはこれから紹介します！

## WHERE
カラムのデータの**特定**ができます。
今回の場合、同じテーブルでカラムは金額と商品名を指定してます
500円以下の商品だけを取得しています。
```sql:sample.sql
SELECT price, item
FROM order_history
WHERE price <= 500;
```
| 金額   | 商品   |
|-----|--------|
| 200 | おにぎり |
| 300 | りんご  |
| 500 | 洗剤    |

## LIKE演算子

ある文字を含むデータを取得したい場合LIKE演算子を使う。
指定したカラムがOOを含むレコードを分析。
%OO%で囲んであげることでOOが入ってる全てを分析できる。
OO%これで前方一致、 %OOこれで後方一致
％のことをワイルドカードという
```sql:sample.sql
SELECT item
FROM order_history
WHERE item LIKE "%おにぎり%";
```
すいません名前が似てる商品がなかったのでここで作ります

| 商品   |
|--------|
| おにぎり |
| たらこおにぎり  |
| 洗剤    |
| 電気ケトル |
| コーヒー豆 |
| 梅干しおにぎり  |

このようなテーブルがあるとします取得結果はこうなります
| 商品   |
|--------|
| おにぎり |
| たらこおにぎり  |
| 梅干しおにぎり  |

おにぎりが入ってる商品を全部取得しました。

## NOT演算子
条件を満たさないデータを取得することができる。
指示したデータ以外を分析する感じ。
```sql:sample.sql
SELECT name,item
FROM order_history
WHERE NOT name LIKE "田中";
```
結果はこちら、田中さんのデータだけ取得しないように命令しました。
| 購入者 | 商品   |
|--------|--------|
| 鈴木     | りんご  |
| 鈴木     | 電気ケトル |
| 鈴木     | コーヒー豆 |

## IS NULL  IS NOT NULL
NULLとは中身が何かわからない、保存されていない、空欄のこと。
注意：NULLは＝が使えない!
```sql:sample.sql
SELECT category
FROM order_history
-- 指定したcategoryのデータがNULLを分析し取得する
WHERE category IS NULL;
-- 指定したcategoryのデータがNULLじゃないデータを分析し取得する
WHERE category IS NOT NULL;
```
## AND演算子
AND演算子は、**複数の条件**を両方とも満たすデータを取得する時に使う
```sql:sample.sql
SELECT category, name, item
FROM order_history
WHERE category = "食品"
AND name = "田中";
```
カテゴリーと購入者と商品を取得し、カテゴリーが食品**かつ**購入者が田中さんの場合
| カテゴリー | 購入者 | 商品   |
|--------|--------|--------|
| 食品     | 田中      | おにぎり |

田中さんの他の商品は洗剤とタオルでカテゴリーが生活用品なので取得はできませんでした！
~~田中さんは洗剤とタオルだけの予定がお腹空いておにぎりを買ったんでしょうね〜~~

## OR演算子
OR演算子は、**複数の条件**から**どちらかを満たす**データを取得する時に使う
```sql:sample.sql
SELECT category, name, item
FROM order_history
WHERE category = "食品"
OR name = "田中";
```
カテゴリーと購入者と商品を取得し、カテゴリーが食品**または**購入者が田中さんの場合
| カテゴリー | 購入者 | 商品 |
|----------|------|------|
| 食品     | 田中 | おにぎり |
| 食品     | 鈴木 | りんご  |
| 生活用品 | 田中 | 洗剤   |
| 食品     | 鈴木 | コーヒー豆 |
| 生活用品 | 田中 | タオル |

生活用品と鈴木さんの電気ケトルが条件に一致しないので取得されませんでした

## ORDER BY
取得したデータを並び替えすることができる
並べ方は降順(DESC)が大きい数から→小さい数
昇順(ASC)が小さい数から→大きい数
WHEREと併用することができる
```sql:sample.sql
SELECT name, item, price
FROM order_history
ORDER BY price DESC;
```

降順なので金額が大きい順に取得してみました。
| 購入者 | 商品       | 金額    |
|------|---------|-------|
| 鈴木  | 電気ケトル | 10000 |
| 鈴木  | コーヒー豆 | 1200  |
| 田中  | タオル     | 700   |
| 田中  | 洗剤       | 500   |
| 鈴木 |   りんご     | 300   |
| 田中  | おにぎり   | 200   |


## LIMIT
最大何件取得するかを決めることができる。
WHEREと併用可能
ORDER BYとも併用できる **LIMITは末尾にする必要がある。**
```sql:sample.sql
SELECT name, item, price
FROM order_history
ORDER BY price DESC;
LIMIT 3;
```
先ほどの金額が大きい順のデータを3件取得してみました。
| 購入者 | 商品       | 金額    |
|------|---------|-------|
| 鈴木  | 電気ケトル | 10000 |
| 鈴木  | コーヒー豆 | 1200  |
| 田中  | タオル     | 700   |

# 検索結果を加工する系

## DISTINCT
検索結果から重複するデータを取り除くことができる

```sql:sample.sql
SELECT DISTINCT(name)
FROM order_history;
```
| name |
|------|
| 田中  |
| 鈴木  |

重複がなくなりました

## SUM関数
保存されたデータの合計を計算してわかる
WHEREを使うと条件も指定できる

```sql:sample.sql
SELECT SUM(price) AS "鈴木さんの合計金額"
FROM order_history
WHERE name = "鈴木";
```
鈴木さんの金額の合計を取得できます。 ASを使うことで取得したデータに名前をつけれます。
| 鈴木さんの合計金額 |
|--------------|
| 12500        |

## AVG関数

指定したカラムに保存されたデータの平均を計算してわかる。
WHEREを使うと条件も指定できる

```sql:sample.sql
SELECT ROUND(AVG(price), 0) AS "鈴木さんの平均合計金額"
FROM order_history
WHERE name = "鈴木";
```

今回は金額の平均が四捨五入して取得される。

| 鈴木さんの平均合計金額 |
|-------------------|
| 4767              |

## COUNT関数
指定したカラムに保存されたデータの合計数を計算。 
SUMとの違いはカラムに保存された**数値**データの合計値を計算
COUNTは指定したカラムに含まれる**レコード数**をカウント
注意：**null**はカウントされないです！
ただし、 * を使うことで全てのカラムをカウントよってレコードの数を計算してくれる。
この場合nullもカウントされる。
もちろんWHEREと併用し条件も組み込める

```sql:sample.sql
SELECT COUNT(*) AS "全てのレコードの数をカウント"
FROM order_history;
```

| 全てのレコードの数をカウント |
|---------------------|
| 6                   |

食品カテゴリーを条件としてレコード取得

```sql:sample.sql
SELECT COUNT(*) AS "食品のレコードの数をカウント"
FROM order_history
WHERE category = "食品";
```
| 食品のレコードの数をカウント |
|---------------------|
| 3                   |

## MAX関数, MIN関数

MAXは最大、MINは最小のデータを取得
取得したいデータが最小または最大の１つだけの場合
ORDER BY,LIMITを使わずに取得できる。
もちろんWHEREと併用し条件も組み込める


```sql:sample.sql
SELECT MAX(price) AS "一番高いやつ"
FROM order_history;
```
今回は最大金額１つだけを求めてみました
| 一番高いやつ |
|------------|
| 10000      |

## GROUP BY
指定したカラムで同じデータを持つレコード達がグループ化できる！
そこにSUM関数を使うとその日付の合計金額がわかる。
注意：必ず集計関数を使うこと。　ここで紹介した集計関数とはSUM ,AVG,COUNT,MAX,MINのこと

```sql:sample.sql
SELECT SUM(price), purchase_date, name
FROM order_history
GROUP BY purchase_date, name;
```

| SUM(price) | 購入日 | 購入者 |
|------------|---------------|------|
| 10300      | 2023-04-02    | 鈴木  |
| 1400       | 2023-04-03    | 田中  |
| 1200       | 2023-04-03    | 鈴木  |


合計金額と購入日と購入者を取得して、購入者と購入日をグループ化している。 
こうすることでこの購入日に買った物と人物がグループに分けられわかりやすくなる。

鈴木さんは4/2に買った合計金額と4/3に買った合計金額
田中さんは4/3にしか買ってないので4/3しかない。
WHEREでさらに細かくグループ分けすることができる！

例えば、カテゴリーで生活用品のみを条件とすると
```sql:sample.sql
SELECT SUM(price), purchase_date, name
FROM order_history
WHERE category ="生活用品"
GROUP BY purchase_date, name;
```

| SUM(price) | 購入日 | 購入者 |
|------------|---------------|------|
| 10000      | 2023-04-02    | 鈴木  |
| 1200       | 2023-04-03    | 田中  |

単純にカテゴリー食品を合計金額から引っこ抜いただけ！


## 10: HAVING
**GROUP BYでグループ化したデータをさらに絞り込みたい時に使う**
集計関数使わなければ   WHERE price >= 1000で1000円以上を検索とできるが
なぜ、WHEREじゃないの？
理由は実行される順番にある。例えば、1000円以上の物だけ取得したいとなった時に
WHEREは一番最初に実行されるので集計関数で合計される前に絞り込まれてしまう
そのため**実際の合計金額**がバグる、なのでWHEREではなくHAVINGを使うちなみにHAVINGは一番最後に実行される。
そのためちゃんと集計関数を行い計算をした後にグループ化してそこから
1000以上の金額を取得する。こんな感じの流れになっている。
思いついたことなので果たして合ってるかは不安ですが
集計関数で計算できない物は例えば文字列とかはWHEREで検索
集計関数で出された合計金額から特定の金額を出す場合は HAVINGなのかなと解釈してます。
### 追記

WHEREはテーブル全体が検索対象、　HAVINGはグループ化されたデータが検索対象です。

```sql:sample.sql
SELECT SUM(price), purchase_date, name
FROM order_history
GROUP BY purchase_date, name
HAVING SUM(price) > 10000;
```
| SUM(price) | 購入日 | 購入者 |
|------------|---------------|------|
| 10300      | 2023-04-02    | 鈴木  |

合計金額が10000円以上のデータを取得しています。

# 終わり
ざっとまとめてみました！

クエリ文の最後にセミコロン忘れがちなので注意！！！！！

**ここまでみてくださりありがとうございます！**