【SQL】複数行の値を1行にまとめる方法(LISTAGG / string_agg / GROUP_CONCAT)

SQL
記事内に広告が含まれています。

はじめに

日頃から Amazon Redshift を使っていて、複数行の値を1行にまとめたいときに LISTAGG を使っていました。
ただ、他のデータベース(MySQLやPostgreSQLなど)で同じことをしようとすると、書き方が微妙に違うことに気付きました。
そこで今回は、主要な3つのデータベース(Oracle/PostgreSQL/MySQL)で「複数行の値を1行にまとめる方法」を整理します。

DBごとの関数対応表

データベース関数名
Oracle / RedshiftLISTAGGLISTAGG(name, ‘区切り文字’)
PostgreSQLstring_aggstring_agg(name, ‘区切り文字’)
MySQLGROUP_CONCATGROUP_CONCAT(name SEPARATOR ‘区切り文字’)

テーブルの例

itemsテーブル

idname
1りんご
2みかん
3バナナ
4ぶどう
5もも

各DBでの書き方例

Oracle / Redshiftの場合

SELECT
  LISTAGG(name, ', ') AS names
FROM
  items;

→ 出力例

names
りんご, みかん, バナナ, ぶどう, もも

LISTAGG(列名, ', ') で複数行の値をカンマ区切りにまとめられます。

※RedshiftはPostgreSQLをベースにしていますが、string_aggは使えず、LISTAGGが利用できるようです。

PostgreSQLの場合

SELECT
  string_agg(name, ', ') AS names
FROM
  items;

string_agg(列名, ', ') で複数行の値をカンマ区切りにまとめられます。

MySQLの場合

SELECT
  GROUP_CONCAT(name SEPARATOR ', ') AS names
FROM
  items;

GROUP_CONCATSEPARATOR に区切り文字を指定します(デフォルトはカンマ,)。

補足:DISTINCTで重複を除外する

どのDBでも、DISTINCTを使うと重複を除外して連結できます。

-- PostgreSQLの例
SELECT
  string_agg(DISTINCT name, ', ') AS names
FROM
  items;

まとめ

  • LISTAGGOracle / Redshift で利用可能
  • PostgreSQL では string_agg
  • MySQL では GROUP_CONCAT
  • DISTINCT で重複を除外できる

さいごに

SQL Fiddleというサイト(以下リンク先)を使うと気軽にブラウザで各DBを試すことができて便利でした。
https://sqlfiddle.com/

最後までお読みいただきありがとうございました。

皆さんからのコメントやSNSでのシェア、嬉しい投稿をいただくと本当に励みになります。

もしこの記事が気に入ったら感想をコメントやSNSでシェアしていただけると嬉しいです。

皆さんの声を聞かせてくださいね!

SQL
tetsuをフォローする
簿記はじめるってよ

コメント

タイトルとURLをコピーしました