web-dev-qa-db-ja.com

1つの列の複数の結果行を1つに連結し、別の列でグループ化する

私はこのようなテーブルを持っています

Movie   Actor   
  A       1
  A       2
  A       3
  B       4

映画の名前とその映画のすべての俳優を取得したいのですが、結果を次のような形式にしたいです:

Movie   ActorList
 A       1, 2, 3

どうすればいいですか?

101
Chin

集約関数 string_agg() (Postgres 9.0以降):

SELECT movie, string_agg(actor, ', ') AS actor_list
FROM   tbl
GROUP  BY 1;

1GROUP BY 1は位置参照であり、この場合のGROUP BY movieのショートカットです。

string_agg()では、入力としてデータ型textが必要です。他の型は明示的にキャストする必要があります(actor::text)-unlesstextへの暗黙的なキャストが定義されている-他のすべての文字型(varcharcharacter"char")の場合他のいくつかのタイプ。

isapir commented のように、ORDER BY句を集約呼び出しに追加して、ソートされたリストを取得できます(必要な場合)。のような:

SELECT movie, string_agg(actor, ', ' ORDER BY actor) AS actor_list
FROM   tbl
GROUP  BY 1;

ただし、通常は、サブクエリで行をソートする方が高速です。見る:

167

そのためにarray_agg関数を使用できます。

SELECT "Movie",
array_to_string(array_agg(distinct "Actor"),',') AS Actor
FROM Table1
GROUP BY "Movie";

結果:

| MOVIE | ACTOR |
-----------------
|     A | 1,2,3 |
|     B |     4 |

このSQLFiddle を参照してください

詳しくは 9.18。集約関数 をご覧ください。

34
hims056