【ざっくりSQL】疲れててもわかるSQLチートシート(選択, 挿入, 更新, 削除, 結合)

# この記事の目的・・・！
- 書式とかは抜きにしてぱっと見で知りたい SQL がわかること
- すぐ使えること

# 環境・・・！
Postgresql 15 で実行してます
ただ，SQL 自体はだいたいどの DBMS でも同じような感じです

# 選択
`select` を確認しましょう

まずは下のクエリでテーブルとデータを作成しておきます

```SQL
CREATE TABLE foods (
    food_id VARCHAR(20) PRIMARY KEY,
    food_name VARCHAR(20),
    stock INTEGER,
    type_name VARCHAR(20)
);

INSERT INTO foods
VALUES
    ('food_1', 'カップラーメン（醬油）', 5, 'インスタント'),
    ('food_2', 'カップラーメン（塩）', 10, 'インスタント'),
    ('food_3', 'カップラーメン（高級味噌）', 15, 'インスタント'),
    ('food_4', '納豆', 1, '米のお供'),
    ('food_5', '鮭', 1, '米のお供'),
    ('food_6', '美味しいパスタ', 5, '作ったお前');
```

![Foods.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/0fa2953e-515c-4684-453f-324b9af14b04.png)

## 基本
```SQL
SELECT * FROM foods;
```
![Foods.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/0fa2953e-515c-4684-453f-324b9af14b04.png)

## WHERE
`stock` が 10 以上のデータだけを `select` してみます

```SQL
SELECT * FROM foods WHERE stock >= 10;
```
![Foods_where.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/847bded3-5cb4-b681-94a0-2ec158fd2321.png)

## GROUP BY
`type_name` ごとにまとめてみましょう
尚，`GROUP BY` で表示できるデータは以下の通りです

- `GROUP BY` で指定したカラム
- `SUM` や `COUNT` などの集約関数に指定したカラム

```SQL
SELECT
	type_name,
	COUNT(stock) AS "行数",
	SUM(stock) AS "残数合計"
FROM foods
GROUP BY type_name;
```

![Foods_groupby.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/c3184696-fac4-c1e9-c31c-5266ee47ad89.png)

## HAVING
`GROUP BY` でまとめた後に条件で絞るときは `HAVING` を使いやす
`WHERE` は使えないのでご注意を

では，`type_name` でまとめたデータの内，
行数が 2 以上のデータを表示しやしょう

```SQL
SELECT
	type_name,
	COUNT(stock) AS "行数",
	SUM(stock) AS "残数合計"
FROM foods
GROUP BY type_name
HAVING COUNT(stock) >= 2;
```
![Foods_having.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/c39d6c49-c261-c0c2-ea2d-e9c0df39764b.png)

## ORDER BY
表示順を決めたい時は `ORDER BY` を使います
一番最後に指定しやす

指定は以下の通りです
- 降順（大きい順）を指定する時は `DESC` を指定
- 昇順（小さい順）を指定する時は `ASC` を指定
- 何も指定しない場合は降順

では残数合計の降順で表示してみましょう


```SQL
SELECT
	type_name,
	COUNT(stock) AS "行数",
	SUM(stock) AS "残数合計"
FROM foods
GROUP BY type_name
HAVING COUNT(stock) >= 2
ORDER BY SUM(stock) DESC;
```

![Foods_orderby.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/b8b2213f-dcec-c3d7-6223-6774cf1d135a.png)

# 挿入
データの挿入は `INSERT` でやりやす

```SQL
INSERT INTO foods
VALUES
	('food_7', '素パスタ', 100, 'ベネチアン'),
	('food_8', 'ソーライス', 20, '美食');
```

![insert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/581faa91-2d1d-fec3-a86a-62579a76042b.png)

# 更新
データの更新は `UPDATE` でやりやす
`food_id` が `food_8` のデータの，
`food_name` を `バター醬油まぶしご飯`，
`stock` を `30` に更新してみましょう

```SQL
UPDATE foods
SET
	food_name = 'バター醬油まぶしご飯',
	stock = 30
WHERE
	food_id = 'food_8'
```

![update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/18a5b3fd-da79-2250-5d2c-38021f7ac3f4.png)

# 削除
先ほど挿入・変更したデータを削除してみやしょう
`delete` でやりやす

```SQL
DELETE FROM foods WHERE food_id in ('food_7', 'food_8');
```

![delete.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/de6c41d9-5871-e900-b630-90f166a7be86.png)

# 結合
## JOIN
以下のテーブルを用意しておきます
左が `menu` テーブルで，右が `category` テーブルです
![join_tables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/ed909bd1-d028-00ed-6d70-655e8a3083f9.png)


### INNER JOIN
左と右のテーブルで条件が一致したものだけを結合しやす
左（`menu`）と右（`category`）で `category_id` が同じものを結合してみやす

#### ON
`ON` を使った結合はこんな感じですます
```SQL
SELECT *
FROM
	menu AS l
INNER JOIN
	category AS r
ON
	l.category_id = r.category_id
```

![inner_join_on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/346466bc-89a6-7b01-8053-b1f12b679c6b.png)

#### 行数が増える例
見たように左と右で同じものだけを結合するので，行数が減るイメージです
が，結合条件に複数行該当するデータがある場合は増加しますよの例です
![increase_join.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/0bc442c4-1f95-91fc-1a82-104fc725461c.png)


#### USING
`USING` を使った結合は以下の通りですます
因みに，`USING` で指定した `category_id` が一番左に行ってます

```SQL
SELECT *
FROM
	menu AS l
INNER JOIN
	category AS r
USING(category_id);
```
![inner_join_using.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/46b5efb1-69f2-3845-b4bd-2515bc3c5f80.png)

#### NATURAL
`NATURAL` にすると，自動的に左と右で同じカラムを結合条件に使って結合いたす
今の例では左と右で同じなのは `category_id` のみで，それを使って結合です

また，結合に使ったカラムは `USING` と同じで一番左にいくます

今の例では `USING` と同じ結果になりまふ

```SQL
SELECT *
FROM
	menu AS l
NATURAL INNER JOIN
	category AS r;
```

### LEFT JOIN
`LEFT JOIN` では左と右のテーブルで条件が一致したものを結合しますが，
左の方は条件に当てはまってるやつがいなくても残ります（右には NULL が入りやす）

`ON`，`USING`，`NATURAL` の挙動は `INNER JOIN` と同じです

では例を見てみましょ
```SQL
SELECT *
FROM
	menu AS l
LEFT JOIN
	category AS r
ON
	l.category_id = r.category_id
```

![left_join.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/3af36ef6-0d0e-12fa-75c4-73bda75bbb0a.png)

### RIGHT JOIN
`RIGHT JOIN` では左と右のテーブルで条件が一致したものを結合しますが，
右の方は条件に当てはまってるやつがいなくても残ります（左には NULL が入りやす）

`ON`，`USING`，`NATURAL` の挙動は `INNER JOIN` と同じです

では例を見てみましょ
```SQL
SELECT *
FROM
	menu AS l
RIGHT JOIN
	category AS r
ON
	l.category_id = r.category_id
```

![right_join.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/a3765e06-e863-e477-b7f4-9353b3586630.png)

### CROSS JOIN
左と右の総当たりです
左に `n` 行，右に `m` 行ある場合，結果は `n×m` 行になりやす

```SQL
SELECT *
FROM
	menu AS l
CROSS JOIN
	category AS r
```

![cross_join.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/8c731ec7-6ce5-f2e7-5d87-8aa6dd161b7f.png)

## UNION
同じカラム数のテーブルを縦に結合するのが `UNION` です
重複は削除されます
`UNION ALL` であれば，重複削除はなく純粋に全部縦に結合です

```SQL
SELECT * FROM up
UNION
SELECT * FROM down
```

![union.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/11777f66-5440-aa20-2a9f-5fe7513e7e66.png)

## EXCEPT
同じカラム数のテーブルの内，
上にあるテーブルから下のテーブルと共通のものを減らすのが `INTERSECT` です
重複は削除されます
`EXCEPT ALL` であれば，重複削除はなく減らすます

![except.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/9e42f0c7-28d5-3ed3-6169-901b79dca110.png)


```SQL
SELECT * FROM up
UNION
SELECT * FROM down
```

## INTERSECT
同じカラム数のテーブルの内，
上にあるテーブルと下のテーブルで共通のものを取り出すのが `INTERSECT` です
重複は削除されます
`INTERSECT ALL` であれば，重複削除はなく純粋に共通のものを抽出すます

```SQL
SELECT * FROM up
INTERSECT
SELECT * FROM down
```

![intersect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/ef247fad-89c1-2437-2ba5-f21d312d12f9.png)