ここではグループ化(集約)について学習します。 select 文に group by 句を指定することでレコードをグループ化し、合計値や平均値を求めることができます。group by 句のあとにはグループ化するカラム名を指定します。

group by 列名

一般的に group by 句はグループ化したレコードの合計値を求める sum 関数や、平均値を求める avg 関数といったグループ関数を組み合わせて使用します。

グループ関数 - sum 関数

sum 関数はグループ化した値の合計値を取得します。次のSQLは courses テーブルの category_id 列でグループ化し、category_id ごとに learning_time 列の合計値を出力します。

MariaDB [eldb]> select category_id, sum(learning_time) 
    ->          from courses group by category_id;
+-------------+--------------------+
| category_id | sum(learning_time) |
+-------------+--------------------+
|        NULL |                100 |
|           1 |                120 |
|           2 |                 50 |
+-------------+--------------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

グループ関数 - avg 関数

avg 関数はグループ化した値の平均値を取得します。次のSQLは courses テーブルの category_id 列でグループ化し、category_id ごとに learning_time 列の平均値を出力します。

MariaDB [eldb]> select category_id, avg(learning_time) 
    ->          from courses group by category_id;
+-------------+--------------------+
| category_id | avg(learning_time) |
+-------------+--------------------+
|        NULL |           100.0000 |
|           1 |            40.0000 |
|           2 |            50.0000 |
+-------------+--------------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

グループ関数 - count 関数

count 関数はグループ化したデータの個数を取得します。次のSQLは courses テーブルの category_id 列でグループ化し、category_id ごとに learning_time 列のデータの個数を出力します。

MariaDB [eldb]> select category_id, count(learning_time) 
    ->          from courses group by category_id;
+-------------+----------------------+
| category_id | count(learning_time) |
+-------------+----------------------+
|        NULL |                    1 |
|           1 |                    3 |
|           2 |                    1 |
+-------------+----------------------+
3 rows in set (0.00 sec)

MariaDB [eldb]> 

グループ関数には他にも最大値を取得する max 関数や最小値を取得する min 関数などがあります。

having

group by 句には having 句によってグループ化した結果に対する条件指定ができます。

group by 列名 having 条件式

たとえば having 句を使うことでグループ化した合計値が 100 以上や、グループ化したデータの個数が10個以上のような条件を指定できます。

次のSQLは courses テーブルの category_id 列でグループ化し、category_id ごとに learning_time 列のデータの個数を出力します。このとき having 句によって、グループ化した learning_time 列のデータの個数が 1 のものだけを出力します。

MariaDB [eldb]> select category_id, count(learning_time) 
    ->          from courses group by category_id 
    ->                       having count(learning_time) = 1;
+-------------+----------------------+
| category_id | count(learning_time) |
+-------------+----------------------+
|        NULL |                    1 |
|           2 |                    1 |
+-------------+----------------------+
2 rows in set (0.00 sec)

MariaDB [eldb]>