集計関数 COUNT/SUM/AVG/MAX/MIN

このレッスンで分かること

  • COUNT / SUM / AVG / MAX / MIN は複数行を 1 行に集約する関数です
  • SUM AVG は NULL を無視、COUNT(*) は NULL も含めて行を数えます
  • 空テーブルでは SUM AVG は NULL、COUNT は 0 を返します

集計関数 COUNT/SUM/AVG/MAX/MIN とは

データの個数、合計、平均などを算出する集計関数の使い方を学びます。本レッスンでは、集計関数 COUNT/SUM/AVG/MAX/MIN の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

業務システムやデータ分析の現場では「件数を数える」「合計を出す」「平均値を取る」「最大・最小を調べる」といった集計が日常的に求められます。たとえば EC サイトなら「今日の注文件数」「本日の売上合計」「顧客あたりの平均購入額」「最高単価の商品」「最も安い商品の価格」が代表的な指標です。これらをアプリケーション側で 1 件ずつ取得して JavaScriptPython で合計するのは非効率で、データ量が増えると一気に重くなります。SQL の 集計関数 はこの処理を データベース 側で高速に実行する仕組みで、CRUD と並んで実務必須のスキルです。

このレッスンでは 5 つの基本集計関数 COUNT / SUM / AVG / MAX / MIN の使い方と、それぞれが NULL や空テーブルに対してどう振る舞うかを学びます。集計関数はこれから学ぶ GROUP BYHAVING の土台でもあるので、ここで土台をしっかり固めましょう。

集計関数を一言でいうと「たくさんの行を 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 内部では次のような流れになります。

diagram (will load when visible)

図の流れを順序リストで書き直すと、次の通りです。

  1. FROM でテーブルを読み込む
  2. WHERE で対象行を絞り込む
  3. 集計関数が行をまとめて 1 行の結果にする
  4. 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(列名) で数えると、件数が小さくなって平均がずれることがあります。

よくある落とし穴

空テーブルに対して SUMAVG を使うと結果は 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 つができることを確認しましょう。

  1. 集計関数 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  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);

期待される出力

cnttotal_priceavg_pricemax_pricemin_price
714448020640.0000000000001280001200

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...