読者です 読者をやめる 読者になる 読者になる

GROUP BY のイメージ

MySQL

ただ並べ替えるだけの「GROUP BY」じゃなくて、指定されたカラムで分けて、分けられたそれぞれで考える というイメージ。

mysql> select * from users;                                                                          +----+------+------+------+
| id | name | age  | sex  |
+----+------+------+------+
|  1 | hoge |   12 |    1 |
|  2 | foo  |   76 |    0 |
|  3 | bar  |   45 |    0 |
|  4 | hoge |   34 |    0 |
|  5 | foo  |   44 |    1 |
|  6 | bar  |   24 |    1 |
+----+------+------+------+

これを以下のような name, man_age, woman_age カラムのような男女別の年齢を出すことを考える。

+------+---------+-----------+
| name | man_age | woman_age |
+------+---------+-----------+
| bar  |      24 |        45 |
| foo  |      44 |        76 |
| hoge |      12 |        34 |
+------+---------+-----------+

出してみる

まずは、hoge, foo, bar それぞれでまとめたいので、GROUP BY name として分ける。

mysql> select name from users;
+------+
| name |
+------+
| hoge |
| foo  |
| bar  |
| hoge |
| foo  |
| bar  |
+------+
6 rows in set (0.00 sec)

mysql> select name from users group by name;
+------+
| name |
+------+
| bar  |
| foo  |
| hoge |
+------+
3 rows in set (0.00 sec)

また、CASE を使うことで if else のような操作ができる。

mysql> select name,case when sex = 1 then age else 0 end as man_age, case when sex = 0 then age else 0 end as woman_age from users;
+------+---------+-----------+
| name | man_age | woman_age |
+------+---------+-----------+
| hoge |      12 |         0 |
| foo  |       0 |        76 |
| bar  |       0 |        45 |
| hoge |       0 |        34 |
| foo  |      44 |         0 |
| bar  |      24 |         0 |
+------+---------+-----------+
6 rows in set (0.00 sec)

上記の表を name ごとにそれぞれ合計すれば出したい表ができる。

mysql> select name,sum(case when sex = 1 then age else 0 end) as man_age, sum(case when sex = 0 then age else 0 end) as woman_age from users group by name;
+------+---------+-----------+
| name | man_age | woman_age |
+------+---------+-----------+
| bar  |      24 |        45 |
| foo  |      44 |        76 |
| hoge |      12 |        34 |
+------+---------+-----------+
3 rows in set (0.00 sec)

まとめ

GROUP BY name ときたら、「name で分けてそれぞれで考える」 かつ並べ替えるというイメージ