Waka blog.

MySQLのGROUP_CONCATの概要とその注意点について

はじめに

MySQLにはGROUP_CONCATという、グループ内の複数の行の値を連結して一つの文字列に変換できる便利な機能があります。

その使い方と注意点について記載していきます

GROUP_CONCATの使い方

基本的な使い方

以下のように使用します。この例ではグループに所属するユーザーの名前を連結して取得するイメージです。

SELECT groups.name, GROUP_CONCAT(users.name) AS user_names
FROM groups
JOIN users ON users.group_id = groups.id
GROUP BY groups.name;

デフォルトではカンマ区切りで取得します。下記のような取得結果になります。

groups.name

user_names

営業グループ

営業一郎,営業二郎,営業三郎

開発グループ

開発春子,開発夏子,開発秋子,開発冬子

カンマ以外の区切り文字を使用する

SEPARATORオプションを使用することで、カンマ以外の任意の区切り文字を使用することが可能です。

以下の例では / 区切りで文字列を連結しています。

SELECT groups.name, GROUP_CONCAT(users.name SEPARATOR '/') AS user_names
FROM groups
JOIN users ON users.group_id = groups.id
GROUP BY groups.name;

以下のような出力結果になるイメージです。

groups.name

user_names

営業グループ

営業一郎/営業二郎/営業三郎

複数のカラムの連結

GROUP_COCATの引数にカンマ区切りでカラム名を追加していくことで、それらのカラムの内容を連結して出力することが可能です。

以下の例ではusers.idとusers.nameを : で繋げています。

SELECT groups.name, GROUP_CONCAT(users.id, ":", users.name SEPARATOR '/') AS user_names
FROM groups
JOIN users ON users.group_id = groups.id
GROUP BY groups.name;

以下のような出力結果になるイメージです。

groups.name

user_names

営業グループ

1:営業一郎/2:営業二郎/3:営業三郎

並べ替え

GROUP_CONCAT内では order by 句が使用して、並び替え後に連結することも可能です。

以下の例ではusers.idの降順で並び替えを行った後、連結しています。

SELECT groups.name, GROUP_CONCAT(users.id, ":", users.name ORDER BY users.id DESC SEPARATOR '/') AS user_names
FROM groups
JOIN users ON users.group_id = groups.id
GROUP BY groups.name;

以下のような出力結果になるイメージです。

groups.name

user_names

営業グループ

3:営業三郎/2:営業二郎/1:営業一郎

使い方の説明は以上になります。

注意点

MySQLのGROUP_CONCATですが、連結して取得可能な文字列のデフォルトの長さが1024文字であることに注意が必要です。

1024文字を超える場合は、それ以降の文字列が切り捨てられてしまうため、意図した値が取得できない可能性があります。

出力可能な文字の長さの確認方法

以下のsqlを実行することで確認可能です

SHOW VARIABLES LIKE 'group_concat_max_len';

Valiable_name

Value

group_concat_max_len

1024

下記のようにgroup_concat_max_lenのサイズを大きくすることも可能ですが、DBサーバーへの負荷が高まることを考えると、採用は慎重になるべきでしょう。

set session group_concat_max_len=10000;

以上です。

GROUP_CONCATは大変便利な関数ですが、最大長について気をつけながら使い所を見極めていきたいです。