> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL の集計関数

> MySQL で COUNT、SUM、AVG、MIN、および MAX が多数の行を 1 つの値にまとめる仕組み、そのすべてが NULL を飛ばす理由、および COUNT(*) と COUNT(column) の違い。

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

ここまでのクエリはすべて行を返しました。集計関数は多数の行を読み、1 つの値を
返します。件数、合計、平均、最大値です。質問が 1 行ではなく集合についてのもので
あるとき、最初に手に取るものです。

始める前に `mysql -u root -p sakila` でクライアントを開いてください。

## 集計関数の仕組み

```sql theme={null}
SELECT AGGREGATE_FUNCTION(COLUMN_NAME)
FROM TABLE_NAME;
```

`AGGREGATE_FUNCTION` を下の関数のいずれかに、`COLUMN_NAME` を読み取る列に、
`TABLE_NAME` をテーブルに置き換えます。

| 関数 | 返すもの |
| - | - |
| `COUNT(*)` | 行の数。NULL を含む |
| `COUNT(column)` | その列に値がある行の数 |
| `SUM(column)` | 合計 |
| `AVG(column)` | 平均 |
| `MIN(column)` | 最小値 |
| `MAX(column)` | 最大値 |

`GROUP BY` がなければテーブル全体が 1 つのグループなので、結果は常にちょうど
1 行です。カテゴリごとに 1 行を得るには、[GROUP BY](https://villagesql.com/docs/ja/tutorial/group-by.md) を
使います。

## 例

### 行を数える

```sql theme={null}
SELECT COUNT(*) AS films FROM film;
```

```text theme={null}
+-------+
| films |
+-------+
|  1000 |
+-------+
1 row in set (0.00 sec)
```

テーブルに何が入っていても 1 行です。集計関数は必ず答えを返します。

### 複数の集計を一度に

```sql theme={null}
SELECT MIN(length) AS shortest, MAX(length) AS longest, AVG(length) AS mean
FROM film;
```

```text theme={null}
+----------+---------+----------+
| shortest | longest | mean     |
+----------+---------+----------+
|       46 |     185 | 115.2720 |
+----------+---------+----------+
1 row in set (0.00 sec)
```

それぞれが同じ 1,000 行を読みます。デフォルトの見出しは式全体になるため、
[エイリアス](https://villagesql.com/docs/ja/tutorial/column-aliases.md)で名前を付けてください。

### 金額の列を合計する

```sql theme={null}
SELECT SUM(amount) AS takings, COUNT(*) AS payments FROM payment;
```

```text theme={null}
+----------+----------+
| takings  | payments |
+----------+----------+
| 67406.56 |    16044 |
+----------+----------+
1 row in set (0.00 sec)
```

## COUNT(\*) と COUNT(column) は別の質問

`COUNT(*)` は行を数えます。`COUNT(column)` はその列に値がある行を数えるため、
NULL を飛ばします。

```sql theme={null}
SELECT COUNT(*) AS rows_total, COUNT(address2) AS with_a_value
FROM address;
```

```text theme={null}
+------------+--------------+
| rows_total | with_a_value |
+------------+--------------+
|        603 |          599 |
+------------+--------------+
1 row in set (0.00 sec)
```

603 件の住所のうち、4 件には 2 行目がまったくありません。残りの 599 件は
空文字列を持っており、`COUNT` はそれを他と同じ値として扱います。`COUNT` が
見ているのは NULL かどうかであり、空白かどうかではありません。[IS NULL](https://villagesql.com/docs/ja/tutorial/is-null.md)
のレッスンでその違いを扱います。

## すべての集計関数は NULL を飛ばす

このルールは `COUNT` に限ったものではありません。どの集計関数も NULL を見ない
ため、何も入っていない列には平均する対象がありません。id の平均を取るのは
無意味な計算ですが、このクエリがそれを行うのは、`original_language_id` が
Sakila で唯一、すべての行で NULL である列だからです。

```sql theme={null}
SELECT COUNT(*) AS films,
       COUNT(original_language_id) AS with_a_value,
       AVG(original_language_id) AS mean
FROM film;
```

```text theme={null}
+-------+--------------+------+
| films | with_a_value | mean |
+-------+--------------+------+
|  1000 |            0 | NULL |
+-------+--------------+------+
1 row in set (0.00 sec)
```

割るものが何もなかったため、`AVG` は 0 ではなく NULL を返しました。これが
最も重要になるのは、ときどきしか値が入っていない列に対する `AVG` です。平均は
全行ではなく値を持つ行に対するものであり、この 2 つの数は同じではありません。
対象が何もないときの `SUM` も NULL ですが、対象が何もないときの `COUNT` は 0 です。

## まとめ

* 多数の行を 1 つの値にまとめるには集計関数を使います。
* `GROUP BY` がないときは、ちょうど 1 行が返ると考えてください。
* `COUNT(*)` は行の数、`COUNT(column)` は値を持つ行の数と読んでください。
* すべての集計関数は NULL を飛ばすため、平均は値を持つ行に対するものです。
* 対象が何もないとき、`SUM` と `AVG` は 0 ではなく NULL を返すと考えてください。

## 関連項目

* [GROUP BY](https://villagesql.com/docs/ja/tutorial/group-by.md) — 全体で 1 行ではなく、カテゴリごとに 1 行の結果
* [COUNT DISTINCT](https://villagesql.com/docs/ja/tutorial/count-distinct.md) — 行ではなく異なる値を数える
* [IS NULL](https://villagesql.com/docs/ja/tutorial/is-null.md) — これらの関数が飛ばす値
* [MySQL の GROUP BY のパフォーマンス](https://villagesql.com/docs/ja/guides/group-by-having.md) — 大規模な集計のコスト


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.