MySQLのGROUP_CONCATの使い方を解説!

MySQLのGROUP_CONCATは指定したカラムに含まれている値をGROUP BYで指定したグループごとに連結させた文字列を表示させることができる便利な関数です。この記事ではGROUP_CONCATの使い方を解説しています。

コンテンツ [表示]

  1. 1MySQLのGROUP_CONCATの使い方
  2. 1.1GROUP_CONCATの基本的な使い方
  3. 1.2区切り文字を指定
  4. 1.3昇順、降順を指定
  5. 1.4複数カラムを指定

MySQLのGROUP_CONCATは指定したカラムに含まれている値を連結させた文字列を表示することができます。

この記事ではMySQLのGROUP_CONCATの使い方を解説していきます。

MySQLのGROUP_CONCATの使い方

GROUP_CONCATの基本的な使い方

基本的な使い方はGROUP_CONCATの引数に指定したカラムの値をカンマ区切りで連結した文字列を表示してくれます。

構文

GROUP_CONCAT(カラム名)

それでは実際にGROUP_CONCATを使ってみましょう。

まずは下記のようなusersテーブルとmessagesテーブルとそれのデータを準備しました。

mysql> SHOW TABLES;
+------------------+
| Tables_in_testdb |
+------------------+
| messages         |
| users            |
+------------------+
2 rows in set (0.00 sec)

mysql> DESC users;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> SELECT * FROM users;
+----+--------+
| id | name   |
+----+--------+
|  1 | taro   |
|  2 | jiro   |
|  3 | hanako |
+----+--------+
3 rows in set (0.00 sec)

mysql> DESC messages;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| user_id | int(11)     | YES  |     | NULL    |                |
| message | varchar(50) | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM messages;
+----+---------+---------------+
| id | user_id | message       |
+----+---------+---------------+
|  1 |       1 | hello         |
|  2 |       1 | This is a pen |
|  3 |       2 | Great!!!      |
|  4 |       2 | Big apple!    |
|  5 |       3 | Hi!           |
|  6 |       3 | I love you.   |
+----+---------+---------------+
6 rows in set (0.00 sec)

messagesテーブルのuser_idカラムはusersテーブルのidカラムに紐づく外部キーになります。

usersテーブルの1つのレコードに対して、messagesテーブルの複数レコードが存在している状態です。

最初にGROUP_CONCATを使用せずに表示してみましょう。

mysql> SELECT users.id, users.name, messages.user_id, messages.message FROM users JOIN messages ON users.id = messages.user_id GROUP BY users.id;
+----+--------+---------+----------+
| id | name   | user_id | message  |
+----+--------+---------+----------+
|  1 | taro   |       1 | hello    |
|  2 | jiro   |       2 | Great!!! |
|  3 | hanako |       3 | Hi!      |
+----+--------+---------+----------+
3 rows in set (0.00 sec)

messageカラムに表示されるのはそれぞれ1つのレコードの値しか表示されず、重複したものについては表示されていません。

では、GROUP_CONCATを使って重複して表示されていない値も表示されるようにしてみましょう。

mysql> SELECT users.id, users.name, messages.user_id, GROUP_CONCAT(messages.message) FROM users JOIN messages ON users.id = messages.user_id GROUP BY users.id;
+----+--------+---------+--------------------------------+
| id | name   | user_id | GROUP_CONCAT(messages.message) |
+----+--------+---------+--------------------------------+
|  1 | taro   |       1 | hello,This is a pen            |
|  2 | jiro   |       2 | Great!!!,Big apple!            |
|  3 | hanako |       3 | Hi!,I love you.                |
+----+--------+---------+--------------------------------+
3 rows in set (0.00 sec)

GROUP_CONCATを使うことによって、複数レコードの値をカンマ区切りで連結した文字列として表示されています。

これでGROUP_CONCATの基本的な使い方はできるかと思います。次から区切り文字や昇順、降順などの条件を指定して表示していきましょう。

区切り文字を指定

GROUP_CONCATの中でSEPARATORを用いることで区切り文字を指定して複数レコードの値を連結することができます。

mysql> SELECT users.id, users.name, messages.user_id, GROUP_CONCAT(messages.message SEPARATOR ' ') FROM users JOIN messages ON users.id = messages.user_id GROUP BY users.id;
+----+--------+---------+----------------------------------------------+
| id | name   | user_id | GROUP_CONCAT(messages.message SEPARATOR ' ') |
+----+--------+---------+----------------------------------------------+
|  1 | taro   |       1 | hello This is a pen                          |
|  2 | jiro   |       2 | Great!!! Big apple!                          |
|  3 | hanako |       3 | Hi! I love you.                              |
+----+--------+---------+----------------------------------------------+
3 rows in set (0.00 sec)

デフォルトのカンマ区切りからSEPARATORで指定した空白文字でmessageカラムの値が区切られていますね。

昇順、降順を指定

GROUP_CONCATの中でORDER BYを使用することで、指定したカラムの順番(昇順、降順)で連結して表示することが出来ます。

mysql> SELECT users.id, users.name, messages.user_id, GROUP_CONCAT(messages.message ORDER BY messages.id) FROM users JOIN messages ON users.id = messages.user_id GROUP BY users.id;
+----+--------+---------+-----------------------------------------------------+
| id | name   | user_id | GROUP_CONCAT(messages.message ORDER BY messages.id) |
+----+--------+---------+-----------------------------------------------------+
|  1 | taro   |       1 | hello,This is a pen                                 |
|  2 | jiro   |       2 | Great!!!,Big apple!                                 |
|  3 | hanako |       3 | Hi!,I love you.                                     |
+----+--------+---------+-----------------------------------------------------+
3 rows in set (0.00 sec)

mysql> SELECT users.id, users.name, messages.user_id, GROUP_CONCAT(messages.message ORDER BY messages.id DESC) FROM users JOIN messages ON users.id = messages.user_id GROUP BY users.id;
+----+--------+---------+----------------------------------------------------------+
| id | name   | user_id | GROUP_CONCAT(messages.message ORDER BY messages.id DESC) |
+----+--------+---------+----------------------------------------------------------+
|  1 | taro   |       1 | This is a pen,hello                                      |
|  2 | jiro   |       2 | Big apple!,Great!!!                                      |
|  3 | hanako |       3 | I love you.,Hi!                                          |
+----+--------+---------+----------------------------------------------------------+
3 rows in set (0.00 sec)

複数カラムを指定

最後にGROUP_CONCATの引数で複数カラムを指定してみたいと思います。

今回は下記のようなテーブルとデータを用意しました。

mysql> DESC users;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| family_name | varchar(10) | YES  |     | NULL    |                |
| first_name  | varchar(10) | YES  |     | NULL    |                |
| group_id    | int(11)     | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM users;
+----+-------------+------------+----------+
| id | family_name | first_name | group_id |
+----+-------------+------------+----------+
|  1 | yamada      | taro       |        1 |
|  2 | sato        | jiro       |        1 |
|  3 | tanaka      | hanako     |        2 |
|  4 | kato        | sachiko    |        2 |
+----+-------------+------------+----------+
4 rows in set (0.00 sec)

mysql> DESC groups;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM groups;
+----+-------+
| id | name  |
+----+-------+
|  1 | men   |
|  2 | women |
+----+-------+
2 rows in set (0.00 sec)

複数カラムを指定する際にはカンマ区切りで指定します。複数カラムの文字列の値を連結してから、複数レコードの値をカンマ区切って表示してくれます。

mysql> SELECT users.id, group_concat(family_name, first_name) AS name, groups.name AS group_name FROM users JOIN groups ON users.group_id = groups.id GROUP BY users.group_id;
+----+--------------------------+------------+
| id | name                     | group_name |
+----+--------------------------+------------+
|  2 | satojiro,yamadataro      | men        |
|  4 | katosachiko,tanakahanako | women      |
+----+--------------------------+------------+
2 rows in set (0.00 sec)
GeekHive採用サイト

関連記事