【保存版】GROUP_CONCAT関数を超えた!MySQLで複数行をカンマ区切りにする4つの方法
MySQLで複数の行をカンマ区切り単一行として取得する方法
GROUP_CONCAT関数 は、SELECTクエリ内で指定した列の値をカンマ区切りで連結し、1つの文字列として返す関数です。
基本的な構文
SELECT GROUP_CONCAT(DISTINCT 列名) AS 列名_alias
FROM テーブル名
[WHERE 条件]
[GROUP BY グループ化列];
例
下記のテーブル articles
があり、各記事に紐づくキーワードをカンマ区切りで1行に取得したい場合を例として説明します。
CREATE TABLE articles (
article_id INT PRIMARY KEY,
title VARCHAR(255),
keyword VARCHAR(255)
);
INSERT INTO articles (article_id, title, keyword) VALUES
(1, 'MySQL入門', 'データベース', 'SQL'),
(2, 'Webサイト構築', 'HTML', 'CSS', 'JavaScript'),
(3, '機械学習の基礎', '人工知能', 'データ分析'),
(1, 'MySQL応用例', 'トランザクション', 'ロック');
この場合、以下のクエリで各記事IDと、それに紐づくキーワードをカンマ区切りで1行ずつ取得できます。
SELECT article_id, GROUP_CONCAT(DISTINCT keyword) AS keywords
FROM articles
GROUP BY article_id;
結果
article_id | keywords
--------- | --------
1 | データベース, SQL, トランザクション
2 | HTML, CSS, JavaScript
3 | 人工知能, データ分析
補足
DISTINCT
キーワードを省略すると、重複するキーワードもカンマ区切りで連結されます。ORDER BY
句を使用して、キーワードの並び順を指定することができます。GROUP BY
句を省略すると、すべての行が1つのカンマ区切り文字列に連結されます。
CREATE TABLE books (
book_id INT PRIMARY KEY,
title VARCHAR(255),
author VARCHAR(255)
);
INSERT INTO books (book_id, title, author) VALUES
(1, 'ハリー・ポッターと賢者の石', 'J.K.ローリング'),
(2, 'ハリー・ポッターと秘密の部屋', 'J.K.ローリング'),
(3, 'ハリー・ポッターとアズカバンの囚徒', 'J.K.ローリング'),
(4, '君の名は。', '新海誠'),
(5, '天気の子', '新海誠');
SELECT book_id, GROUP_CONCAT(DISTINCT author) AS authors
FROM books
GROUP BY book_id;
book_id | authors
--------- | --------
1 | J.K.ローリング
2 | J.K.ローリング
3 | J.K.ローリング
4 | 新海誠
5 | 新海誠
このサンプルコードでは、以下の点に注目してください。
books
テーブルには、書籍ID、タイトル、著者名の3つの列があります。GROUP_CONCAT関数
を使用して、author
列の値をカンマ区切りで連結しています。DISTINCT
キーワードを使用しているので、重複する著者名は連結されません。GROUP BY book_id
句を使用しているので、書籍IDごとに著者名をまとめることができます。
MySQLで複数の行をカンマ区切り単一行として取得するその他の方法
サブクエリを使用する
SELECT article_id,
(
SELECT GROUP_CONCAT(keyword)
FROM articles AS a2
WHERE a2.article_id = a1.article_id
) AS keywords
FROM articles AS a1;
FOR LOOPを使用する
SELECT article_id,
(
SELECT GROUP_CONCAT(keyword SEPARATOR ',')
FROM (
SELECT keyword
FROM articles AS a2
WHERE a2.article_id = a1.article_id
) AS sub
) AS keywords
FROM articles AS a1;
Window関数を使用する
SELECT article_id,
STRING_AGG(keyword, ',') OVER (PARTITION BY article_id) AS keywords
FROM articles;
それぞれの方法のメリットとデメリット
方法 | メリット | デメリット |
---|---|---|
GROUP_CONCAT関数 | シンプルでわかりやすい | サブクエリを使用するため、複雑なクエリになると見にくくなる可能性がある |
サブクエリ | 柔軟性が高い | 複数のクエリを結合するため、処理速度が遅くなる可能性がある |
FOR LOOP | 可読性が高い | コードが冗長になる可能性がある |
Window関数 | 最新のMySQLバージョンでのみ使用可能 | 他の方法に比べて知名度が低い |
- シンプルでわかりやすい方法を求める場合は、GROUP_CONCAT関数 がおすすめです。
- 柔軟性が必要な場合は、サブクエリ を使用する方法がおすすめです。
- 可読性を重視する場合は、FOR LOOP を使用する方法がおすすめです。
- 最新のMySQLバージョンを使用している場合は、Window関数 を使用する方法も検討できます。
MySQLで複数の行をカンマ区切り単一行として取得するには、GROUP_CONCAT関数 をはじめ、様々な方法があります。それぞれの方法のメリットとデメリットを理解した上で、状況に応じて適切な方法を選択しましょう。
mysql database