GROUP BY句を使って集計!COUNTやHAVINGとの合わせ技も解説【SQL】

SQLでグループ化して集計したい場合はGROUP BY句を使います。

本記事では、GROUP BY句の使い方から、COUNT関数などの集約関数との併用方法、WHERE句やHAVING句との合わせ技についても具体例を交えて解説しています。

GROUP BY句の使い方

GROUP BYはデータをグルーピングするために使います。チームごとの得点を算出したり、カテゴリーごとの売上を算出するなど使用用途は様々です。

使い方も難しくなく、基本構文は下記です。

SQL
SELECT カラム名
FROM テーブル名
GROUP BY グループ化するカラム名;

GROUP BY カラム名で特定のカラムを起点としてグループ化を行います。

1点注意すべき点は、SELECT句にはGROUP BY句で指定したカラムか集約関数(COUNT・SUM・MAXなど)のみ指定できるということです。

例えば、GROUP BYidしか指定していないのに、SELECT句でidemailを指定することはできません。GROUP BYidだけを指定しているなら、SELECT句で指定できるのもidだけです。

サンプルデータ

下記のとおり、usersテーブルを用意します。

idnameageaddress
1山田25東京都
2鈴木34神奈川県
3佐藤29大阪府
4佐々木47東京都
5大野25東京都
6小池34大阪府

カラムを指定してグループ化する

では、サンプルデータを元にグループ化を行ってみましょう。

検索クエリ

usersテーブルを居住地ごとでグループ化する

SQL
SELECT address
FROM users
GROUP BY address;

GROUP BY addressで居住地ごとにグループ化を行なっています。

実行結果

address
神奈川県
東京都
大阪府

グループ化されて重複がないように居住地情報を取得できました。

複数カラムを指定する

次に、複数カラムを指定してグループ化する方法を見ていきます。

検索クエリ

usersテーブルの名前と居住地の組み合わせでグループ化する

SQL
SELECT age, address
FROM users
GROUP BY age, address;

GROUP BY age, addressとすることで、ageカラムとaddressカラムの組み合わせでグループ化されます。

実行結果

ageaddress
25東京都
29大阪府
34大阪府
34神奈川県
47東京都

nameカラムの値とaddressカラムの値が一致するレコードは統合されました。年齢が34歳のレコードは2つありますが、居住地が異なるためグループ化されていません。

グループ化して数を数える(COUNT関数)

次に、グループ化した上でそれぞれのグループに存在するレコードの数をカウントする方法を見ていきます。

数を数えるためには、集約関数の一つであるCOUNT関数を使います。

検索クエリ

usersテーブルを居住地ごとでグループ化し、グループごとのレコード数を取得する

SQL
SELECT address, COUNT(*)
FROM users
GROUP BY address;

GROUP BY addressで居住地ごとにグループ化した上で、COUNT(*)でレコードの数を取得しています。

COUNT(*)GROUP BYでは指定していませんが、集約関数なのでSELECT句で使えます。

実行結果

addressCOUNT(*)
大阪府2
東京都3
神奈川県1

居住地ごとにグループ化した上で、それぞれのレコードの数を取得できました。

COUNT関数以外にもSUM関数・MAX関数・MIN関数・AVG関数などの集約関数を使って集計が可能です。

【SQL】SUM関数を使って指定カラムの合計値を求める SQLのMAX関数(最大値)・MIN(最小値)の使い方を徹底解説 【SQL】AVG関数で平均値を求める方法を分かりやすく解説

条件指定をする

WHERE句とHAVING句はどちらも検索条件を指定することができます。

この2つの違いと、それぞれの使い方を見ていきましょう。

GROUP BY句とWHERE句の違い

違いはクエリが実行される順番にあります。

  • WHERE句・・GROUP BY句の前に実行される
  • HAVING句・・GROUP BY句の後に実行される

WHERE句はグループ化する前に条件を指定できるのに対して、HAVING句はグループ化した後に条件指定ができます。

初心者が最初は困惑する部分でもあるので、繰り返しになりますが実行される順番が違うという点をとにかく覚えておきましょう!

グループ化する前に条件指定をする方法(WHERE句を使う)

グループ化する際にWHERE句を使って条件指定する場合を見ていきましょう。

検索クエリ

年齢が30歳以下の人に絞った上で、居住地ごとにグループ化する

SQL
SELECT address
FROM users
WHERE age =< 30
GROUP BY address;

GROUP BY addressと居住地でグループ化する前に、WHERE age =< 30と条件指定を行っています。

実行結果

address
大阪府
東京都

居住地が神奈川県の人は年齢が30歳より大きいため、除外されていることが分かります。

グループ化した後に条件指定をする方法(HAVING句を使う)

次に、グループ化する際にHAVING句を使って条件指定する場合を見ていきましょう。

検索クエリ

居住地ごとにグループ化し、最年少の人が30歳を超えているグループのみ取得する

SQL
SELECT address, MIN(age)
FROM users
GROUP BY address
HAVING MIN(age) > 30;

GROUP BY addressと居住地ごとでグループ化した上で、HAVING MIN(age) > 30と条件指定を行っています。特定カラムの最小値を取得するにはMIN関数を使用します。

また、MIN(age)GROUP BYでは指定していませんが、集約関数なのでSELECT句で使えます。

実行結果

addressMIN(age)
神奈川県34

東京都、大阪府の人の最年少は30歳を下回っているため、検索結果から除外されていることが分かります。

このように、集約関数(MIN関数・COUNT関数・SUM関数・AVG関数など)を使用する際にHAVING句を使うことが多いです。

内容のまとめ

  • GROUP BY句は特定のカラムでグループ化する時に使う
  • GROUP BY句の基本構文はSELECT カラム名 FROM テーブル名 GROUP BY グループ化するカラム名
  • SELECT句にはGROUP BY句で指定したカラムか集約関数(COUNT・SUM・MAXなど)のみ指定できる
  • 複数カラムでグループ化する際は、GROUP BY カラム名1, カラム名2とカンマ区切りでカラムを指定する
  • グループごとのレコード数を取得する場合はCOUNT関数を使う
  • 条件指定にはWHERE句とHAVING句の2つがあり、違いはクエリが実行される順番にある
  • WHERE句はGROUP BY句の前に実行されるのに対して、HAVING句はGROUP BY句の後に実行される