【SQL初級】SELECT文による集計方法（集計関数とグループ化）

##はじめに

SQLを用いてデータベースを扱う際の「**SELECT文**」について少し掘り下げていきます。

SELECT文には検索結果をひとまとめにして集計する方法があります。
集計をうまく活用すれば単にデータを蓄積するだけではなく、蓄積したデータの分析や活用も行うことができます。

この記事ではSQLにおける基本的なデータ集計の方法である「**集計関数**」と「**グループ化**」についてまとめていきます。

##対象読者

今回取り扱う記事の内容は`SQLを覚えたての初心者レベル`程度を対象としています。
初学者向けの本を読み終えた方への復習や、別角度からまとめた資料になれば幸いです。

##目次

- [集計関数](#集計関数)
 - [NULL値の扱い](#null値の扱い)
- [グループ化](#グループ化)
 - [AS](#as)
 - [HAVING](#having)
- [SELECT文の構文まとめ](#select文の構文まとめ)

##集計関数

SQLには、指定した列の値を集計する**集計関数**（集合関数・集約関数）が用意されています。
次のような関数があります。

```
SUM (列名)　　　　　-　　　　列の合計を求める
AVG (列名)　　　　　-　　　　列の平均を求める
MAX (列名)　　　　　-　　　　列の最大値を求める
MIN (列名)　　　　　-　　　　列の最小値を求める
COUNT (*)　　　　　　-　　　　検索結果の行数を求める(NULLを含む)
COUNT (列名)　　　　　-　　　　検索結果の行数を求める(NULLを除く)
```

**例）家計簿から出金額の合計を求める**

```
SELECT SUM(出金額) AS 出金額の合計
    FROM 家計簿
```

![SUM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227208/7c4cd829-8f27-37ed-9ed2-528c987cee19.png)

集計関数には他にも様々な種類がありますが、今回はSQL初級者向け記事なので省略します。
[その他の集約関数一覧]
(https://docs.snowflake.com/ja/sql-reference/functions-aggregation.html)


###NULL値の扱い

検索結果にNULL値が含まれる場合は`SUM`, `AVG`, `MAX`, `MIN` 等ではNULL値を無視して集計結果を表示します。
また、同じCOUNT関数でも`COUNT(*)`はNULLを含んで集計しますが、`COUNT(列名)`ではNULL値を無視して集計が行われます。

そのため以下のように、作業が行われていないことによって生じるNULL値を０として扱って集計を行いたい場合は`COALESCE関数`等を使用して記述します。

**例）貯金口座から毎月の出金額の平均を求める**

```
SELECT AVG(COALESCE(出金額,0)) AS 出金額の平均
    FROM 貯金口座
```

![出金額.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227208/c787dbec-85ae-4875-0efa-912ea5db657b.png)

NULLの挙動についても様々な種類がありますが、今回はSQL初級者向け記事なので省略します。

しかし実務でも**NULLの取扱いは注意が必要**という記事は多いのでいくつか参考に載せておきます。
[本当は怖いNULLの世界（データベース）]
(https://qiita.com/s_yasunaga/items/9be1f3a5cf212b4f87a3)
[NULL≠空文字を理解する（UPDATEでNULLを扱う場合について）]
(https://style.potepan.com/articles/23824.html)


##グループ化

**SELECT文**で`GROUP BY 列名`を指定すると、指定した列の内容が一致する行をグループ化（一つの行にまとめる）できます。
※SELECT直後の列名には（集計関数を除いて）GROUP BY句に指定した列名を用います

```
SELECT (列名) GROUP BY (列名)
```

**例）販売表から「商品コードごとの販売数量の合計」を求め、商品コードと販売数量の合計を抽出する**

```
SELECT 商品コード, SUM (販売数量)
    FROM 販売表
    GROUP BY 商品コード
```

![販売表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227208/b01e2d98-d4b9-dac0-9483-da23bc22df72.png)


###AS

集合関数で求めた列に、「**AS**」を使って新たに別名を付けることができます。
**例）上記で求めたSUM（販売数量）の列に別名を付ける**

```
SELECT 商品コード, SUM (販売数量) AS 合計数量
    FROM 販売表
    GROUP BY 商品コード
```

![AS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227208/b37e411f-7132-d817-7076-2fb7cc51898e.png)



###HAVING

`GROUP BY 列名`で指定したグループに対して、「**HAVING**」を使ってグループに対する条件を付けることができます。

```
GROUP BY (列名) HAVING グループに対する条件
```

**例）販売表から「商品コードごとの販売数量の合計が250を超える商品」の商品コードと販売数量の合計を抽出する**

```
SELECT 商品コード, SUM (販売数量) AS 合計数量
    FROM 販売表
    GROUP BY 商品コード HAVING SUM (販売数量) > 250
```

![HAVING.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227208/846a4468-2483-ddd0-0858-ebc3f86d920b.png)



##SELECT文の構文まとめ

最後に、集計を含んだSELECT文の構文を以下に整理しておきます。

```
 SELECT 列名または集計関数
   FROM テーブル名
 [WHERE 条件式]
 [GROUP BY グループ化列名]
[HAVING 集計結果に対する条件式]
```

なお、[ ]で括られた部分は任意で記述するものになります。

またSELECT文に関しては前回記事も参考になると思いますので復習にご使用ください。
[【SQL初級】SELECT文とCREATE文について（基本まとめ）]
(https://qiita.com/msys825/items/0d21258f861527ea43c6)


---
**参考にした書籍**
 [栢木先生の基本情報技術者教室]
(https://www.amazon.co.jp/%E4%BB%A4%E5%92%8C03%E5%B9%B4-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8-%E3%82%AF%E3%83%AC%E3%83%90%E3%83%BC%E6%96%B9%E5%BC%8F%E3%81%A7%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B-%E6%A0%A2%E6%9C%A8%E5%85%88%E7%94%9F%E3%81%AE%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E6%95%99%E5%AE%A4-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93/dp/4297117169/ref=sr_1_2_sspa?crid=1D51HD6Z2J968&dchild=1&keywords=%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93&qid=1630744262&sr=8-2-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzVkpIUUc4WEI3WjJIJmVuY3J5cHRlZElkPUEwMjI0NDAxMkcxQVBLOVU3UVdGTiZlbmNyeXB0ZWRBZElkPUEzRzhISDY4TEdUMTFUJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)
 [スッキリわかる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%8B-SQL-%E5%85%A5%E9%96%80-%E3%83%89%E3%83%AA%E3%83%AB215%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4844333933/ref=sr_1_1?ie=UTF8&qid=1499257314&sr=8-1&keywords=%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+%E3%83%89%E3%83%AA%E3%83%AB215%E5%95%8F%E4%BB%98%E3%81%8D)

**その他SQL初級者に参考になると思われる記事**
[【これだけ覚えてたらOK！】SQL構文まとめ](https://qiita.com/tatsuya4150/items/69c2c9d318e5b93e6ccd)
[逆引きSQL構文集 - 集計関数を使用する(基本)]
(https://www.sql-reference.com/summary/summary.html)


---
以上、間違いや修正点ありましたらご指摘よろしくお願いします。