【集約関数】#3 Webディレクター見習いが知識ゼロからSQLを学ぶ

こんにちは、はじめまして! 　saku-chanです!
このアカウントは、社会人1年目のWebディレクター見習い(初心者)がSQLを学ぶ成長記録になっています。
ひよっこから成長する過程を残し、ついでに皆さんからアドバイスを頂けたら良いな! 私と同じように知識ゼロからSQLを始める人の一つの指針になればいいな!という思いで作成しました。
ちなみに、ブログを含め記事などを書いた経験がないため読みづらい部分も多々あるかと思いますが、そこも含めて皆さまアドバイス頂けると嬉しいですmm

◆記事の内容は、**SQL初心者の自分が、同じような初心者の方でも理解しやすいように心がけながら、SQLに関して学んだことを懇切丁寧に**記載しています◆

##目次
- [はじめに](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)
- [集約関数とは](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#%E9%9B%86%E7%B4%84%E9%96%A2%E6%95%B0%E3%81%A8%E3%81%AF)
- [COUNT関数](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#count%E9%96%A2%E6%95%B0)
<br>└[①COUNT(*)](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#count)
<br>└[②COUNT(＜カラム名＞)](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#count%E3%82%AB%E3%83%A9%E3%83%A0%E5%90%8D)
<br>└[③COUNT(DISTINCT ＜カラム名＞)](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#countdistinct-%E3%82%AB%E3%83%A9%E3%83%A0%E5%90%8D)
<br>└[COUNT関数まとめ](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#count%E9%96%A2%E6%95%B0%E3%81%BE%E3%81%A8%E3%82%81)
- [その他の集約関数](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E9%9B%86%E7%B4%84%E9%96%A2%E6%95%B0)
- [まとめ](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#%E3%81%BE%E3%81%A8%E3%82%81)
- [最後に](https://qiita.com/saku-chan/items/71bfa462d8a1384e2965#%E6%9C%80%E5%BE%8C%E3%81%AB)

##はじめに
今回はSQLで使用される集約関数に関して勉強したことを記載します！
前回同様、初めてSQLを勉強する方が気軽に読んでいただける記事になっています^^
ではスタート!

⇒[前回の記事【SELECT句とFROM句】はこちら](https://qiita.com/saku-chan/items/673d910d708a985f1f5b)

⇒[記事一覧](/saku-chan/items/48d36b6ad60d63206a18)

##集約関数とは
そもそも集約関数ってなんでしょうか。

「合計」「平均」「最大値」「最小値」、、、etc

これで何となくイメージがついた方が多いのではないかと思います。(笑)

集約関数は、SQLにおいてテーブルの複数の行を対象に「合計」や「平均」など**集計**を行うために使用するものです。
エクセルの関数と似ているので、理解がしやすいかなと思います。

今回は、そんな集約関数の1つであるCOUNT関数をメインに、いくつかの集約関数を取り上げてみます!

##COUNT関数
まずはCOUNT関数から説明していきます。

COUNT関数はテーブルの**レコード数(行数)を数える**集約関数です。

理解しやすいと思うので、具体例を出して説明します。

テーブル名：friends

| id       |       name |    age    |
|:-----------------:|:------------------:|:------------------:|
| 01             |              けん |        14       |
| 02           |            あおい|       21      |
| 03             |              みほ |       16        |


上記のようなfriendsというデータテーブル[^1]があった時に、


```sql
 SELECT COUNT(*) FROM friends ;
```

このようなクエリ(命令)を実行すると、下記のような結果を得ることが出来ます。

| COUNT(*)      | 
|:-----------------:|
| 3            |  

つまり、このクエリの意味は、
**friendsというテーブルのレコード数(行数)を全行数える**
です。

ポイントとしては、**集約関数はSELECT句に記載する**ことくらいでしょうか。

覚えることが少なくてとっても簡単ですね！

###①COUNT(*)
ではもう少しCOUNT関数に関してお話していきたいと思います。
実はCOUNT関数は上記で説明した使い方を含め3つ使用方法(呼び出し方)があります。

**①COUNT(*)
②COUNT(<カラム名>)
③COUNT(DISTINCT <カラム名>)**

似たり寄ったりでよくわからないと思うので、具体例を見ながら理解していきましょう!

今回使用するのはこちらのテーブルです。
テーブル名：friends_2

|id|       name |    age    |color|
|:-------------:|:-------------:|:------------:|:------------:|
|01|  けん |   14     |red|
|02| あおい|    21    |NULL|
|03|  みほ |   16   |pink|
|04| さやか |    9  |green|
|05|たくや |   16   |NULL|
|06|  あい |    16  |green|

まずは**①COUNT(*)**をつかってみます。

```sql
 SELECT COUNT(*) FROM friends_2 ;
```

このクエリの実行結果は

| COUNT(*)      | 
|:-----------------:|
| 6           |  

となります。
先ほどと同じですね!
**①COUNT(*)**の意味は「テーブルのレコード数[^2]を**全行数える**」でした。

###②COUNT(＜カラム名＞)
続いて**②COUNT<カラム名>**をつかってみます。

テーブル名：friends_2

|id|       name |    age    |color|
|:-------------:|:-------------:|:------------:|:------------:|
|01|  けん |   14     |red|
|02| あおい|    21    |NULL|
|03|  みほ |   16   |pink|
|04| さやか |    9  |green|
|05|たくや |   16   |NULL|
|06|  あい |    16  |green|

```sql
 SELECT COUNT(id) FROM friends_2 ;
```
このクエリの実行結果は

| COUNT(id)      | 
|:-----------------:|
| 6           |  

あれ？先ほどと同じ結果になりました。
では下記のクエリだとどうでしょうか。

```sql
 SELECT COUNT(color) FROM friends_2 ;
```
このクエリの実行結果は

| COUNT(color)      | 
|:-----------------:|
| 4           |  

となります。
クエリ名を「id」から「color」にすると結果が6→4に変わりました。
この理由は、colorのカラムをよーく見てみるとわかります。

例えば2レコード目のcolorカラム。
`NULL`
と記載されています。

いや、`NULL`ってなんやねん！
ってなった方。
ですよね！！気持ち分かります！！
データを扱ったことがある方ならあたりまえに知っていることのようですが、
そのあたりの知識もゼロである自分は、SQLの本を読んで初めてNULLに突然出会ったとき、思わず突っ込みました、、笑

`NULL`は**データベース上でその箇所にデータがないということを表す**表現です。
つまり、今回の例でいくと、2レコード目はidが02で、nameがあおいで、ageが21だということはわかるけど、colorはわからない、ということになります。

まとめると、**②COUNT<カラム名>**の意味は、「指定したカラムの**NULLではないレコード数**を数える」です。

###③COUNT(DISTINCT ＜カラム名＞)
最後に**③COUNT(DISTINCT <カラム名>)**をつかってみます。

テーブル名：friends_2

|id|       name |    age    |color|
|:-------------:|:-------------:|:------------:|:------------:|
|01|  けん |   14     |red|
|02| あおい|    21    |NULL|
|03|  みほ |   16   |pink|
|04| さやか |    9  |green|
|05|たくや |   16   |NULL|
|06|  あい |    16  |green|

```sql
 SELECT COUNT(DISTINCT color) FROM friends_2 ;
```
このクエリの実行結果は

| COUNT(color)      | 
|:-----------------:|
| 3          |  

となります。
どういうことかというと、これは、**値がNULLではないものについて、値の重複を除いたレコード数[^2]を数える**という意味です。
(今回の例だとcolorカラムにはgreenが2つあるので、この重複を除いたred、pink、greenの「3」が表示されています。)

ここで勘が良い方は既にお気づきかもしれませんが、**値の重複を除いた**という部分を**`DISTINCT`**で指定しています。

なので、たとえば

```sql
 SELECT COUNT(DISTINCT age) FROM friends_2 ;
```
というクエリを実行した結果は、

| COUNT(age)      | 
|:-----------------:|
| 4           |  

になります。
16が重複しているので、14、21、9、16を数えた「4」が表示されているということですね。

ちなみにDISTINCTは集計関数でなくても使うことが可能です。

```sql
 SELECT DISTINCT age FROM friends_2 ;
```

このクエリの結果は、

| age   | 
|:-----------------:|
| 14         |  
| 21        |  
| 16         |  
| 9         |  

となります。

###COUNT関数まとめ
改めてCOUNT関数に関してまとめてみます。

①COUNT(\*)
**→テーブルのレコード数[^2]を全行数える**

②COUNT(<カラム名>)
**→指定したカラムのNULLではないレコード数を数える**

③COUNT(DISTINCT <カラム名>)
**→値がNULLではないものについて、値の重複を除いたレコード数[^2]を数える**
(COUNT(DISTINCT <カラム名>)はログデータからユニークユーザー数(固有のユーザー数)を集計する時などによく使われるようです。)

一見わかりづらいかもしれませんが、順を追っていけば大したことは言っていないですね(笑)

##その他の集約関数
最後にさくっとCOUNT関数以外の集約関数をご紹介します!

COUNT関数以外の主な集約関数はこのような感じです。

|集約関数      |  内容 |
|:-----------------:|:------------------:|
|SUM(<カラム名>)          |           指定したカラムの合計 |   
| AVG(<カラム名>)       |            指定したカラムの平均|    
| MAX(<カラム名>)       |              指定したカラムの最大値 |  
| MIN(<カラム名>)       |              指定したカラムの最小値|     

使い方はCOUNT関数と同じで、

```sql
 SELECT SUM(age) FROM friends_2 ;
```

```sql
 SELECT MAX(age) FROM friends_2 ;
```

のように使用できます。

1点注意点としては、COUNT関数と同様に他の集約関数でも**NULLは無視される**ということです。

たとえば、下記のようなテーブル、クエリが存在したとき、


Table名：quiz

| points   | 
|:-----------------:|
|2     |  
| NULL        |  
| 4       |  
|  0      |  
| NULL       |  

```sql
 SELECT AVG(points) FROM quiz ;
```
結果はこのようになります。

| AVG(points)   | 
|:-----------------:|
|2     |  

実行内容は、(2+4+0) ÷ 3です。

ここで注意しなければいけないのは、**`NULL`と`0`は違う**ということです。
`0`は集約関数の対象になるけれど、`NULL`は対象外となります。

今回の例でいくと、
クイズ大会において、`NULL`は不参加、`0`は参加したけど0ポイントだった時、
参加者の平均得点は2ポイント
という感じでしょうか。

このように少し注意は必要ですが、基本さえ覚えてしまえばあとは汎用的に使用できるので、さくっと覚えてしまいましょう!

##まとめ
- 集約関数は、SQLにおいてテーブルの複数の行を対象に集計を行うために使用する
- COUNT関数はテーブルのレコード数(行数)を数える集約関数
- `NULL`はデータベース上でその個所にデータがないということを表す表現
- `NULL`は集約関数で集計する際、対象外になる
- `DISTINCT`は値の重複を除くために使用する

##最後に
今回はCOUNT関数をメインに、集約関数に関してまとめてみました！
SQLが初めてという方でも理解できるような内容になっていると嬉しいです。
ではまた次回！^^

⇒[次の記事【WHERE句】](/saku-chan/items/9cfe22decee081848772)

⇒[記事一覧](/saku-chan/items/48d36b6ad60d63206a18)


[^1]: データが記載してある表
[^2]: 行数