MySQLのGROUP_CONCATで複数行の値を1つのフィールドにまとめてリストとして取得する方法
はじめに
MySQLでは、複数の行に分かれている値を1つのフィールドに連結したリストとして取得したい場面がよくあります。たとえば、科目ごとに受講している学生名をカンマ区切りでまとめて表示したい場合などです。
このような場合は、集約関数のGROUP_CONCAT()を使用することで簡単に実現できます。
本記事では、実際にテーブルを作成し、サンプルデータを使いながらGROUP_CONCAT()の使い方を順を追って解説します。
サンプルテーブルの作成
まず、科目名(SubjectName)と学生名(StudentName)を持つテーブルを作成します。
mysql> create table DemoTable2024
-> (
-> SubjectName varchar(20),
-> StudentName varchar(20)
-> );
Query OK, 0 rows affected (0.62 sec)
テストデータの挿入
次に、INSERT文を使っていくつかのレコードを挿入します。
mysql> insert into DemoTable2024 values('MySQL','Chris');
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable2024 values('MySQL','David');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable2024 values('MongoDB','Bob');
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable2024 values('Java','Sam');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable2024 values('MongoDB','Mike');
Query OK, 1 row affected (0.17 sec)登録データの確認
SELECT文ですべてのレコードを表示してみましょう。
mysql> select *from DemoTable2024;
実行結果は以下のとおりです。
+-------------+-------------+
| SubjectName | StudentName |
+-------------+-------------+
| MySQL | Chris |
| MySQL | David |
| MongoDB | Bob |
| Java | Sam |
| MongoDB | Mike |
+-------------+-------------+
5 rows in set (0.00 sec)
同じ科目名が複数の行に重複して存在していることが確認できます。
GROUP_CONCAT()で複数行を1つのフィールドにまとめる
それが本題となる、異なる行の値を1つのフィールドにリストとして返すクエリです。GROUP_CONCAT()を使い、SubjectNameでグループ化します。
mysql> select SubjectName,group_concat(StudentName)
-> from DemoTable2024
-> group by SubjectName;
実行結果は以下のとおりです。
+-------------+---------------------------+
| SubjectName | group_concat(StudentName) |
+-------------+---------------------------+
| Java | Sam |
| MongoDB | Bob,Mike |
| MySQL | Chris,David |
+-------------+---------------------------+
3 rows in set (0.06 sec)
実行結果のポイント
ご覧のとおり、科目ごとに行がグループ化され、学生名がカンマ区切りのリストとして1つのフィールドにまとめられました。MySQLは「MongoDB」や「MySQL」のような重複する科目名を自動的に1つのグループに集約しています。
区切り文字を変更したい場合
デフォルトの区切り文字はカンマですが、SEPARATOR句を使えば任意の文字に変更できます。
SELECT SubjectName,
GROUP_CONCAT(StudentName SEPARATOR ' / ') AS Students
FROM DemoTable2024
GROUP BY SubjectName;
このクエリを実行すると、「Bob / Mike」のように「 / 」区切りで表示されます。
並び順を指定したい場合
ORDER BY句をGROUP_CONCAT内に記述すれば、リスト内の値の順序も制御できます。
SELECT SubjectName,
GROUP_CONCAT(StudentName ORDER BY StudentName ASC) AS Students
FROM DemoTable2024
GROUP BY SubjectName;
注意点
- GROUP_CONCAT()の結果には最大長の制限(group_concat_max_len、デフォルトは1024バイト)があるため、大量のデータを連結する場合は設定変更が必要です。
- DISTINCTキーワードを組み合わせることで、重複する値を除外したリストを取得することも可能です。
まとめ
MySQLで複数の行の値を1つのフィールドにリストとして返したい場合は、GROUP_CONCAT()とGROUP BYを組み合わせるのが最もシンプルで効果的な方法です。SEPARATORやORDER BYと組み合わせることで、出力形式や並び順も柔軟に制御できますので、ぜひ活用してみてください。
-
MySQLで削除後のAUTO_INCREMENTフィールドを振り直す方法|1,3,5を1,2,3に連番化する
MySQLでは、行を削除した後もAUTO_INCREMENTの値は欠番のまま残ります。例えば、IDが「1,2,3,4,5」のテーブルから「2」と「4」を削除すると、残るのは「1,3,5」です。この記事では、この欠番を詰めて「1,2,3」という連番に振り直す方法を、実際のSQL文と実行結果とともにわかりやすく解説します。 1. サンプルテーブルを作成する まず、AUTO_INCREMENTフィールドを持つテーブルを作成します。 mysql> create table DemoTable1955 ( UserId int NOT NULL AUTO_INCREMENT,
-
MySQLで重複行を除外して1行だけ取得する方法(DISTINCTの使い方)
MySQLで重複行から1行のみを返すには?MySQLのテーブルに同じ値を持つ重複行が存在する場合、DISTINCTキーワードを使うことで、重複を排除した一意な行だけを取得できます。この記事では、実際にテーブルを作成し、データを挿入したうえで、DISTINCTによる重複除去の手順を解説します。1. テーブルを作成するまず、サンプル用のテーブルを作成します。mysql> create table DemoTable1998 ( Name varchar(20) ); Query OK, 0 rows affected (0.61 sec)2. レコードを挿入するINSERTコマンドを