こんにちは、かつコーチです。
「今月の注文件数は何件?」「売上の合計はいくら?」「一番高い商品はいくら?」。
こうした問いに答えるとき、1件ずつデータを目で数える必要はありません。
SQLには、複数行のデータをまとめて計算してくれる集計関数が用意されています。
この記事では、代表的な5つの集計関数COUNT・SUM・AVG・MAX・MINの使い方を、ordersテーブルを例に解説します。
集計関数とは?
複数行を1つの値にまとめる関数
集計関数とは、複数行のデータをまとめて1つの値(件数・合計・平均など)を計算する関数です。
SELECT文の中で使うことで、テーブル全体やグループごとの統計値を求められます。
この記事では、以下のテーブルを例に解説します。
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_name VARCHAR(50),
amount INT,
order_date DATE
);
なぜ集計関数が必要なのか
売上分析やダッシュボード表示など、Webアプリの管理画面では「件数」「合計」「平均」を表示する場面が頻繁にあります。
これをアプリ側のプログラムで1件ずつループして計算することもできますが、大量データではデータベース側で集計した方が圧倒的に高速です。
集計関数を使いこなせるようになると、アプリ側のコードをシンプルに保ちながら、パフォーマンスの良い集計処理を実装できます。
基本の書き方
COUNT:件数を数える
COUNTは、行数を数える集計関数です。
SELECT COUNT(*) AS order_count FROM orders;
COUNT(*)はテーブル全体の行数を数えます。COUNT(カラム名)と書くと、そのカラムがNULLでない行だけを数えるという違いがあるため、後述の「つまずきやすい設定・注意点」で詳しく解説します。
SUM:合計値を求める
SUMは、指定したカラムの数値を合計する集計関数です。
SELECT SUM(amount) AS total_amount FROM orders;
これで、ordersテーブルに記録されているすべての注文金額の合計が求められます。
AVG:平均値を求める
AVGは、指定したカラムの数値の平均を求める集計関数です。
SELECT AVG(amount) AS avg_amount FROM orders;
「1注文あたりの平均単価」を求める際によく使われます。
MAX・MIN:最大値・最小値を求める
MAXは最大値、MINは最小値を求める集計関数です。
SELECT MAX(amount) AS max_amount, MIN(amount) AS min_amount FROM orders;
数値だけでなく、日付や文字列にも使えます。
例えばMAX(order_date)とすれば、最も新しい注文日を取得できます。
GROUP BYと組み合わせてグループごとに集計する
集計関数は、GROUP BYと組み合わせることで真価を発揮します。
SELECT customer_name, COUNT(*) AS order_count, SUM(amount) AS total_amount
FROM orders
GROUP BY customer_name;
これで「顧客ごとの注文件数と合計金額」を1回のクエリで求められます。
GROUP BYの詳しい仕組みは、このシリーズの後続記事で扱います。
よくあるつまずきポイント・エラー対処
COUNT(*)とCOUNT(カラム名)の結果が違う
❌ Before:NULLを含むカラムをそのままCOUNTして、想定より少ない件数が返ってくる
SELECT COUNT(memo) AS memo_count FROM orders;
私が実際にこの違いでハマったことがあります。ordersテーブルのmemo(備考)列は入力必須ではなく、NULLの行が多く存在していました。COUNT(memo)はNULLを除外して数えるため、COUNT(*)で数えた全体の件数よりも少ない値が返ってきて、「なぜ件数が合わないのか」と原因調査に時間がかかりました。
✅ After:「全体の件数」か「NULLを除いた件数」かを意図して使い分ける
SELECT COUNT(*) AS total_count, COUNT(memo) AS memo_filled_count FROM orders;
COUNT(*)は行数そのもの、COUNT(カラム名)は「そのカラムに値が入っている行数」という違いを理解しておくと、この種のズレを未然に防げます。
集計関数と通常のカラムを一緒にSELECTしてエラーになる
❌ Before:GROUP BYの対象になっていないカラムを一緒にSELECTしようとする
SELECT customer_name, order_date, SUM(amount) FROM orders GROUP BY customer_name;
このクエリはMySQLの設定によってはERROR 1055のようなエラーになったり、意図しないorder_dateの値が返ってきたりします。
GROUP BYを使う場合、SELECTに書けるのは「GROUP BYで指定したカラム」と「集計関数」だけというのが基本ルールです。
✅ After:GROUP BYの対象カラムだけを一緒にSELECTする
SELECT customer_name, SUM(amount) FROM orders GROUP BY customer_name;
order_dateごとの情報もあわせて見たい場合は、GROUP BYの対象にorder_dateも加える必要があります。
応用・一歩先の使い方
複数の集計関数を組み合わせたレポートクエリ
実務では、複数の集計関数を1つのクエリにまとめて、簡易的なレポートを作ることがよくあります。
SELECT
customer_name,
COUNT(*) AS order_count,
SUM(amount) AS total_amount,
AVG(amount) AS avg_amount,
MAX(amount) AS max_amount,
MIN(amount) AS min_amount
FROM orders
GROUP BY customer_name;
顧客ごとの注文傾向を、この1本のクエリだけで一覧化できます。
集計結果をHAVINGで絞り込む
「合計金額が10万円を超える顧客だけ表示したい」のように、集計結果自体を条件に絞り込みたい場合は、WHEREではなくHAVINGを使います。
SELECT customer_name, SUM(amount) AS total_amount
FROM orders
GROUP BY customer_name
HAVING SUM(amount) > 100000;
WHEREとHAVINGの違いについては、このシリーズの後続記事で詳しく解説します。
まとめ
この記事のポイント
- COUNT・SUM・AVG・MAX・MINは、複数行を1つの値にまとめる集計関数
- COUNT(*)は全行数、COUNT(カラム名)はNULLを除いた件数を数える
- GROUP BYと組み合わせることで、グループごとの集計ができる
- GROUP BYを使う際は、SELECTに書けるカラムがGROUP BY対象か集計関数に限られる
次に読むべき記事
- SQL DISTINCT 使い方
- SQL GROUP BY 使い方
- SQL HAVING WHERE 違い
タグ: SQL, 初心者向け, 基本文法
