集計関数 COUNT/SUM/AVG/MAX/MIN
このレッスンで分かること
COUNT/SUM/AVG/MAX/MINは複数行を 1 行に集約する関数ですSUMAVGは NULL を無視、COUNT(*)は NULL も含めて行を数えます- 空テーブルでは
SUMAVGは NULL、COUNTは 0 を返します
集計関数 COUNT/SUM/AVG/MAX/MIN とは
データの個数、合計、平均などを算出する集計関数の使い方を学びます。本レッスンでは、集計関数 COUNT/SUM/AVG/MAX/MIN の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
業務システムやデータ分析の現場では「件数を数える」「合計を出す」「平均値を取る」「最大・最小を調べる」といった集計が日常的に求められます。たとえば EC サイトなら「今日の注文件数」「本日の売上合計」「顧客あたりの平均購入額」「最高単価の商品」「最も安い商品の価格」が代表的な指標です。これらをアプリケーション側で 1 件ずつ取得して JavaScript や Python で合計するのは非効率で、データ量が増えると一気に重くなります。SQL の 集計関数 はこの処理を データベース 側で高速に実行する仕組みで、CRUD と並んで実務必須のスキルです。
このレッスンでは 5 つの基本集計関数 COUNT / SUM / AVG / MAX / MIN の使い方と、それぞれが NULL や空テーブルに対してどう振る舞うかを学びます。集計関数はこれから学ぶ GROUP BY や HAVING の土台でもあるので、ここで土台をしっかり固めましょう。
集計関数を一言でいうと「たくさんの行を 1 行の答えにまとめる関数」です。1000 件の注文を 1 つの売上合計にする、と考えるとイメージしやすくなります。
構文と各関数の役割
基本構文は次の通りです。
SQL クエリ
SELECT
COUNT(*) AS row_count,
COUNT(price) AS price_count,
SUM(price) AS total_price,
AVG(price) AS avg_price,
MAX(price) AS max_price,
MIN(price) AS min_price
FROM products;各関数の役割は次のとおりです。
| 関数 | 役割 | NULL の扱い |
|---|---|---|
COUNT(*) | 行数 | NULL でも 1 行と数える |
COUNT(列) | 列が NULL でない行の件数 | 無視 |
SUM(列) | 数値列の合計 | 無視 |
AVG(列) | 数値列の平均 | 無視 (分母にも入らない) |
MAX(列) | 最大値 (数値・文字列・日付) | 無視 |
MIN(列) | 最小値 (数値・文字列・日付) | 無視 |
処理の流れ
集計関数が実行されるとき、SQL 内部では次のような流れになります。
図の流れを順序リストで書き直すと、次の通りです。
FROMでテーブルを読み込むWHEREで対象行を絞り込む- 集計関数が行をまとめて 1 行の結果にする
SELECTで結果列を出力する
つまり「絞り込んだ後に集計する」という順序です。WHERE で先に範囲を狭めると、集計対象が減って高速になります。逆に SELECT 句に集計関数を書いただけでは行は減らず、必ず 1 行にまとめられた結果が返ります。
代表例 1 全行を 1 行に集約
商品テーブル products に複数行のデータがあるとして、件数と合計と平均をまとめて出します。
SQL クエリ
SELECT
COUNT(*) AS cnt,
SUM(price) AS total,
AVG(price) AS average
FROM products;結果は常に 1 行で返り、その行に集計結果が入ります。WHERE がなければ全行が集計対象です。アプリケーション側で 1000 件のレコードを取って合計するより、データベース側で 1 行に集約してから受け取った方がネットワーク転送も処理も大きくに軽くなります。
代表例 2 NULL を含む列の挙動
discount_price 列に NULL がある場合の挙動を確認します。
SQL クエリ
SELECT
COUNT(*) AS cnt_all,
COUNT(discount_price) AS cnt_not_null,
AVG(discount_price) AS avg_discount
FROM products;COUNT(*) は NULL も含めて全行をカウントしますが、COUNT(discount_price) は NULL を除いた件数を返します。AVG も分母が NULL を除いた件数になる点に注意してください。たとえば 10 行のうち 7 行だけ値が入っていれば、AVG は 7 で割った平均になります。
COUNT(*)とCOUNT(列名)は別物です。NULL を含む列をCOUNT(列名)で数えると、件数が小さくなって平均がずれることがあります。
よくある落とし穴
空テーブルに対して
SUMやAVGを使うと結果は NULL になります。COUNTだけは 0 を返すので、件数 0 を 0 として扱いたいならCOUNTを、金額の合計を 0 として扱いたいならCOALESCE(SUM(price), 0)で包むと覚えておきましょう。
もう一つ、MAX / MIN は文字列にも適用できます。MAX(name) は辞書順で最後の名前を返し、MIN(name) は最初の名前を返します。日付列に使うと「最新日」「最古日」を取り出せるので分析でよく登場します。
月次レポートを書くなら「件数と合計と平均」を 1 つの SELECT にまとめると、データベースへのアクセスが 1 回で済んで効率的です。
ここまでの要点
COUNT(*) は行数、COUNT(列) は NULL を除く件数。SUM AVG は NULL 無視。空テーブルで SUM は NULL、COUNT は 0。COALESCE で NULL 防御。
まとめ
COUNT(*)は全行数、COUNT(列名)は NULL を除く件数SUM/AVGは NULL を無視して計算する- 空テーブルでは
SUM/AVGは NULL、COUNTは 0 を返す MAX/MINは数値・文字列・日付すべてに使える- 1 回の SELECT で複数の集計関数をまとめると効率がいい
次のレッスン
次は NULLの扱い方 です。データが存在しない場合に用いられるNULLの扱い方について学習します。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 集計関数 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 集計関数 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
テーブル構造
schema.sql
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
category VARCHAR(30) NOT NULL,
price INT NOT NULL,
stock INT NOT NULL
);
INSERT INTO products (id, name, category, price, stock) VALUES
(1, 'ノートPC', '家電', 128000, 5),
(2, 'マウス', '家電', 2980, 30),
(3, 'キーボード', '家電', 6800, 12),
(4, '小説A', '書籍', 1800, 50),
(5, '小説B', '書籍', 2200, 20),
(6, 'コーヒー豆', '食品', 1500, 40),
(7, '紅茶葉', '食品', 1200, 25);期待される出力
| cnt | total_price | avg_price | max_price | min_price |
|---|---|---|---|---|
| 7 | 144480 | 20640.000000000000 | 128000 | 1200 |