SQLで、格納されたデータをグループ化し、集計する運用は様々な業務で発生します。
本記事では、グループ化を行うGROUP BY句と各種集計関数の使い方について、サンプルコードを交えながらご紹介していきます。
SQLにおけるGROUP BY句の使い方と集計関数の種類
まずは基本的なGROUP BY句の使い方と集計関数の種類と概要について説明していきます。
GROPU BY句の使い方
GROUP BY句は名前の通り、データをグループ化する目的で使用します。
集計を行いたい項目をグループ単位でまとめた上で、各集計処理を実施する流れとなります。
基本構文
GROUP BY句を利用したSQLは下記のような構成となります。
SELECT カラム名[, カラム名, ...] FROM テーブル名 [WHERE 条件式] GROUP BY カラム名[, カラム名, ...];
SELECT句に記述するカラム名は、GROUP BYで指定したカラム名または集計関数のいずれかを設定出来ます。
集計関数の種類
集計関数には下記5つが提供されています。
- SUM: 合計を計算
- AVG: 平均を計算
- COUNT: レコード数を計算
- MAX: 最大値を計算
- MIN: 最小値を計算
サンプルSQLで各集計関数の使い方を確認しよう
では実際にサンプルSQLを実行しながら、各集計関数の使い方を確認していきましょう。
サンプルデータ
今回はサンプルデータとして「animal」テーブルに下記のデータを用意しています。
animal
+------+--------+------+------+ | id | name | age | type | +------+--------+------+------+ | 1 | ハチ | 5 | dog | | 2 | たま | 2 | cat | | 3 | ポチ | 4 | dog | | 4 | しろ | 7 | cat | | 5 | もこ | 3 | bird | | 6 | まる | 5 | dog | | 7 | みく | 3 | cat | | 8 | くろ | 2 | dog | | 9 | ココ | 7 | dog | | 10 | ムギ | 1 | dog | +------+--------+------+------+
SUM関数
まずはSUM関数を利用して、「type」毎の総年齢を計算してみたいと思います。
mysql> select type, sum(age) from animal group by type; +------+----------+ | type | sum(age) | +------+----------+ | dog | 24 | | cat | 12 | | bird | 3 | +------+----------+ 3 rows in set (0.00 sec)
「dog」の合計は「5+4+5+2+7+1=24」、「cat」の合計は「2+7+3=12」、「bird」はデータが1つしかないため「3」が表示されていますね。
AVG関数
今度はAVG関数で、「type」毎の平均年齢を計算してみましょう。
mysql> select type, avg(age) from animal group by type; +------+----------+ | type | avg(age) | +------+----------+ | dog | 4.0000 | | cat | 4.0000 | | bird | 3.0000 | +------+----------+ 3 rows in set (0.00 sec)
「dog」の合計値「24」をレコード数の「6」で割ると平均は「4」、「cat」の合計値「12」をレコード数の「3」で割ると「4」、「bird」はデータが1つしかないため平均も「3」と表示されていますね。
COUNT関数
続いてCOUNT関数で、「type」毎のレコード件数を取得してみます。
mysql> select type, count(age) from animal group by type; +------+------------+ | type | count(age) | +------+------------+ | dog | 6 | | cat | 3 | | bird | 1 | +------+------------+ 3 rows in set (0.00 sec)
それぞれのレコード件数が表示されていることをご確認頂けます。
MAX関数
MAX関数で、「type」毎の最高年齢を確認してみましょう。
mysql> select type, max(age) from animal group by type; +------+----------+ | type | max(age) | +------+----------+ | dog | 7 | | cat | 7 | | bird | 3 | +------+----------+ 3 rows in set (0.00 sec)
サンプルデータの中から「type」毎に最高値のデータが取得されていますね。
MIN関数
同じくMIN関数で「type」毎の最小年齢を確認してみましょう。
mysql> select type, min(age) from animal group by type; +------+----------+ | type | min(age) | +------+----------+ | dog | 1 | | cat | 2 | | bird | 3 | +------+----------+ 3 rows in set (0.00 sec)
「type」毎に最小値の年齢が取得されていることをご確認頂けます。
組み合わせて利用することも可能
集計関数は組み合わせて記述することも可能で、1つSQL文に複数記述することが出来ます。
mysql> select type, sum(age) as sum, avg(age) as avg, count(age) as count, max(age) as max, min(age) as min from animal group by type; +------+------+--------+-------+------+------+ | type | sum | avg | count | max | min | +------+------+--------+-------+------+------+ | dog | 24 | 4.0000 | 6 | 7 | 1 | | cat | 12 | 4.0000 | 3 | 7 | 2 | | bird | 3 | 3.0000 | 1 | 3 | 3 | +------+------+--------+-------+------+------+ 3 rows in set (0.01 sec)
条件指定で集計関数を利用する
GROUP BY句の条件指定には「WHERE」句と「HAVING」句の2箇所に記述する方法が存在しますが、グループ化が実施された後に条件を絞り込む「HAVING」句であれば、集計間数を条件式に利用することが可能です。
mysql> select type, count(age) as count from animal group by type having count > 2; +------+-------+ | type | count | +------+-------+ | dog | 6 | | cat | 3 | +------+-------+ 2 rows in set (0.00 sec)
サンプルでは、グループ化した後の件数が2件以上のデータのみを取得条件として設定しています。
WHERE句はグループ化の前に実施されるため、集計関数を利用した条件を記述することは出来ません。
さいごに: SQLの集計関数を使ってみよう
本記事では、SQLのGROUP BY句と各種集権関数の使い方についてご紹介してきました。
今回ご紹介した内容は、SQL標準規格で定義されている集権関数で、データベース毎に独自の集計関数が提供されていたりもします。
まずは本記事内でも紹介した5つの集計関数の使い方を覚え、応用としてご自身が利用するデータベース独自の集計関数も使いこなせるように挑戦してみてください。
テーブルに実在するカラム名であっても、GROUP BYを利用する場合、グループ化の対象項目以外を取得することは出来ません。