FE EXAM

GROUP BY句(グループ化集計)

指定した列の値ごとに行をまとめて集計するSQLの句。

INTERACTIVE VISUALIZATION
営業グループ
開発グループ
フェーズ
idle
グループ化キー
結果の行数
シナリオ
ステップ1 / 5
STEP 1/5グループ化する前の表これは社員の給与表(給与は万円単位)です。1行が1人を表します。「部署ごとに何人いて、平均給与はいくらか」を知りたいとき、1行ずつ眺めても分かりません。そこで GROUP BY 句で部署ごとに行をまとめていきます。
employeesdeptnamesalary営業Aoki30開発Endo40営業Kato36開発Sato44開発Ueda48
SQL
SELECT dept, COUNT(*), AVG(salary)
FROM employees
解説

📌
GROUP BY句とは

元データ5行GROUP BY2グループ2行営業(2人)開発(3人)

GROUP BY句とは、指定した列の値が同じ行どうしをまとめて1つのグループにし、グループ単位で集計するためのSQLの句です。「○○ごとの合計・平均・件数」を求めたいときに使います。

身近な例で考えると、バラバラのレシートを「店ごとの山」に分けてから、山ごとに合計を出す作業に似ています。まず分け(グループ化)、それから数える・足す(集計)の2段階です。

上のツールで▶ボタンを押すと、キー列(dept)を選び、同じ部署の行をまとめ、各グループに集計関数を適用して「1グループ=1行」の結果になるまでを確認できます。

🧮
集計関数との組合せ

GROUP BY は集計関数(=複数の値を1つにまとめる関数)とセットで使うのが基本です。代表的な集計関数は次のとおりです。
COUNT:件数(行数)を数える
SUM:合計を求める
AVG:平均を求める
MAX / MIN:最大値 / 最小値を求める

SELECT dept, COUNT(*), AVG(salary)
FROM employees
GROUP BY dept;

ポイントは、集計関数が「グループ1つにつき1つの値」を返すことです。だから結果はグループの数だけの行になります。また、SELECT に書ける列はGROUP BY で指定した列か、集計関数に限られます。上のツールの集計ステップで、各部署の人数と平均給与が1つずつ計算される様子を確認できます。

🔗
HAVINGとの関係

WHERE行を絞るGROUP BYまとめるHAVING集計後に絞る

GROUP BY でグループ化・集計したあとの結果に条件をつけたいとき、HAVING句を使います。たとえば「人数が3人以上の部署だけ表示する」といった絞り込みです。

GROUP BY dept
HAVING COUNT(*) >= 3;

処理される順番はWHERE(集計前に各行を絞る)→ GROUP BY(まとめる)→ HAVING(集計後のグループを絞る)です。WHERE は1行ずつの条件、HAVING はグループ(集計値)に対する条件、という役割の違いを押さえておきましょう。HAVING の詳しい動きは別ページで扱います。

🗂️
なぜ GROUP BY で行がまとまるのか

元データ(5行)営業 / 350開発 / 420営業 / 380開発 / 460開発 / 390GROUP BY deptグループ化後(2行)営業グループ350, 380 → COUNT=2, AVG=365開発グループ420, 460, 390 → COUNT=3, AVG=4231グループ = 1行として出力

GROUP BY が「行をまとめる」仕組みはシンプルです。指定した列(キー列)の値が同じ行を1つの束(グループ)にまとめるだけです。たとえば GROUP BY dept なら、dept 列が「営業」の行をすべて1グループ、「開発」の行をすべて1グループとして扱います。

なぜまとめると集計できるのか。グループになった行の集まりに対して集計関数(COUNT・SUM・AVG など)を適用すると、「その束の中の件数」「合計」「平均」をまとめて1つの数値として出せるからです。
・5行あっても営業2行・開発3行の2グループ → 結果は2行になる
・それぞれのグループで「COUNT=行数を数える」「AVG=値を平均する」を実行
・上のツールで「集計」ステップを見ると、各グループ内の salary が1つの平均値に変換される様子を確認できます

身近な例でいうと、クラスを出席番号ではなく「部活ごと」に並べ直して、各部活の人数を数える作業です。並べ直す(グループ化)→数える(集計)の2段階で理解できます。

📏
結果表のルール:SELECT に書ける列は決まっている

SELECT に書いてよいGROUP BY の列 (dept)集計関数 COUNT(*), AVGSELECT に書けないGROUP BY 外の列 (name)集計なしの salary など

GROUP BY を使ったとき、SELECT に書ける列にはルールがあります。書けるのは次の2種類だけです。
GROUP BY で指定した列(グループを代表する値。例:dept
集計関数の結果(例:COUNT(*)AVG(salary)

なぜこのルールがあるのか。GROUP BY でグループ化すると、元の複数の行が「1つのグループ(1行)」に圧縮されます。このときグループ外の列(例:name)はグループ内に複数の値を持つため、「どの値を表示すべきか」が決まりません。

たとえば営業グループには「田中・佐藤」の2人がいます。そこで SELECT name と書いても、「田中」と「佐藤」のどちらを表示すればよいかがわからず、エラーになります。一方 COUNT(*) なら「2人」という1つの値が確定するので、問題なく使えます。

練習問題

🎯
基本情報技術者 練習問題

Q1.GROUP BY句の役割として最も適切なものはどれか。
A.指定した列の値が同じ行をまとめてグループにし、集計の単位を作る
B.結果を指定した列で並べ替える
C.条件に合う行だけを取り出す
D.重複した行を削除する
Q2.「GROUP BY dept」とともに使う集計関数の説明として正しいものはどれか。
A.集計関数は1行ごとに1つの値を返す
B.COUNT(*) はグループ内の行数を返し、グループごとに1つの値になる
C.集計関数は GROUP BY と一緒には使えない
D.AVG は合計を返す関数である
Q3.GROUP BY と HAVING の関係として正しいものはどれか。
A.HAVING はグループ化の前に各行を絞り込む
B.HAVING はグループ化して集計した結果に対して条件を指定する
C.HAVING は並べ替えを行う句である
D.GROUP BY と HAVING は同じ意味である

関連コンテンツ