web-dev-qa-db-fra.com

Concaténer plusieurs lignes de résultat d'une colonne en une, groupées par une autre colonne

Je vais avoir une table comme ça

Movie   Actor   
  A       1
  A       2
  A       3
  B       4

Je veux obtenir le nom d'un film et de tous les acteurs de ce film, et je veux que le résultat soit dans un format comme celui-ci:

Movie   ActorList
 A       1, 2, 3

Comment puis-je le faire?

106
Chin

Plus simple avec la fonction d'agrégation string_agg() (Postgres 9.0 ou version ultérieure):

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

Le 1 dans GROUP BY 1 est une référence de position et un raccourci pour GROUP BY movie dans ce cas.

string_agg() attend le type de données text en entrée. Les autres types doivent être transtypés explicitement (actor::text) - sauf si une conversion implicite en text est définie - ce qui est le cas pour tous les autres types de caractères ( varchar, character, "char") et quelques autres types.

Comme isapir commenté , vous pouvez ajouter une clause ORDER BY dans l'appel d'agrégat pour obtenir une liste triée - si vous en avez besoin. Comme:

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

Mais il est généralement plus rapide de trier les lignes d'une sous-requête. Voir:

178

Vous pouvez utiliser la fonction array_agg pour cela:

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

Résultat:

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

Voir this SQLFiddle

Pour plus d'informations, voir 9.18. Fonctions d'agrégation

39
hims056