コマンド道場

$ man string-agg

STRING_AGG

集約関数

グループの中の値を、区切り文字でつないで 1 つの文字列にする。

呼び出しの形

STRING_AGG(式, 区切り)
STRING_AGG(式, 区切り ORDER BY 式)
STRING_AGG(DISTINCT 式, 区切り)

つまずきやすいところ

  • 並び順を指定しないと、つながる順番は決まりません。STRING_AGG(式, 区切り ORDER BY 式) と、引数の中に ORDER BY を書いてください。

  • 名前が製品ごとに違います(MySQL は GROUP_CONCAT、Oracle は LISTAGG)。移植するときはほぼ確実に書き換えが要ります

  • 件数が多いグループでは非常に長い文字列になります。画面に出す前に件数の上限を考えてください。

  • ORDER BY name の並びは照合順序(多くは文字コード順)です。五十音順で並べたいなら、読み仮名の列を別に持って並べ替えてください。

実行例

結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。

部署ごとに所属者の名前を 1 行にまとめる
SELECT busho_id, STRING_AGG(name, ', ' ORDER BY name) AS meibo, COUNT(*) AS ninzu FROM shain GROUP BY busho_id ORDER BY busho_id
busho_idmeiboninzu
1鈴木1
2中村, 佐藤, 小林, 田中4
3伊藤, 山田, 松本, 高橋4
4山本, 斎藤, 清水3
5加藤, 吉田2
7井上, 木村2
NULL大野, 渡辺2

7

ORDER BY を引数の中に書くことで、並びが毎回同じになります。⚠️ 並び自体は照合順序(文字コード順)なので、五十音順にはなりません。

重複を除いてつなぐ
SELECT STRING_AGG(DISTINCT busho_name, ' / ' ORDER BY busho_name) AS busho_ichiran FROM busho
busho_ichiran
マーケ / 営業 / 基盤 / 法務 / 管理 / 経営 / 開発

1

説明

STRING_AGG は、グループに属する値を区切り文字でつないで 1 つの文字列にします。「部署ごとの所属者を 1 行にまとめて出す」ような一覧を、アプリ側で組み立てずに SQL だけで作れます。

⚠️ 並び順を指定しないと、つながる順番は決まりません。STRING_AGG(name, ', ' ORDER BY name) のように、集約関数の引数の中に ORDER BY を書きます。見慣れない書き方ですが、これが正しい位置です。

NULL は無視されます。すべて NULL なら結果も NULL になります。

⚠️ 名前が製品ごとに違います。MySQL は GROUP_CONCAT、Oracle は LISTAGG、SQL Server は STRING_AGG(区切りの指定方法が違う)です。移植性は低い関数です。

次に読む

関係する関数

根拠にした一次情報