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