1. ホーム
  2. sql

[解決済み】PostgresqlのGROUP_CONCATと同等?

2022-03-29 14:44:20

質問

テーブルがあり、idごとに1行、フィールドの値を連結して引き出したいのですが、可能でしょうか?

私のテーブルでは、例えばこんな感じです。

TM67 | 4  | 32556
TM67 | 9  | 98200
TM67 | 72 | 22300
TM99 | 2  | 23009
TM99 | 3  | 11200

そして、出力したいと思います。

TM67 | 4,9,72 | 32556,98200,22300
TM99 | 2,3    | 23009,11200

MySQLでは、集計関数の GROUP_CONCAT しかし、ここではそれがうまくいかないようです...。PostgreSQLに同等のもの、あるいはこれを実現する別の方法はありますか?

どのように解決するのですか?

これはおそらく良い出発点です(バージョン8.4以上のみ)。

SELECT id_field, array_agg(value_field1), array_agg(value_field2)
FROM data_table
GROUP BY id_field

array_agg は配列を返しますが、それをテキストにCASTし、必要に応じて編集することができます(以下の説明を参照)。

バージョン8.4以前は、使用前に自分で定義する必要があります。

CREATE AGGREGATE array_agg (anyelement)
(
    sfunc = array_append,
    stype = anyarray,
    initcond = '{}'
);

(PostgreSQLのドキュメントからの抜粋)

明確化する。

  • 配列をテキストにキャストすると、結果の文字列は中括弧で始まり、中括弧で終わります。 これらの中括弧は、不要であれば、何らかの方法で削除する必要があります。
  • ANYARRAYをTEXTにキャストすると、埋め込まれたカンマを含む要素が標準的なCSVスタイルでダブルクォートされるため、CSV出力を最もよくシミュレートすることができます。array_to_string() や string_agg() (9.1 で追加された "group_concat" 関数) はカンマを含む文字列を引用しないので、結果として結果のリストの要素数が不正になります。
  • 新しい 9.1 の string_agg() 関数は、内部の結果を最初に TEXT にキャストしません。 そのため、"string_ag(value_field)"はvalue_fieldが整数の場合にエラーを発生させます。"string_ag(value_field::text)"は必要でしょう。 array_ag()メソッドでは、集約後に1回だけキャストが必要です(値ごとにキャストするのではありません)。