Ordre array_agg PostgreSQL

109

Tableau 'animaux':

animal_name animal_type
Tom         Cat
Jerry       Mouse
Kermit      Frog

Requete:

SELECT 
array_to_string(array_agg(animal_name),';') animal_names,
array_to_string(array_agg(animal_type),';') animal_types
FROM animals;

Résultat attendu:

Tom;Jerry;Kerimt, Cat;Mouse;Frog
OR
Tom;Kerimt;Jerry, Cat;Frog;Mouse

Puis-je être sûr que l'ordre dans la première fonction d'agrégation sera toujours le même que dans la seconde. Je veux dire que je n'aimerais pas avoir:

Tom;Jerry;Kermit, Frog;Mouse,Cat
Olo
la source
7
Si vous êtes sur 9.0, vous pouvez remplacer les appels imbriqués par un seulstring_agg()
a_horse_with_no_name

Réponses:

27

Si vous utilisez une version PostgreSQL <9.0, alors:

De: http://www.postgresql.org/docs/8.4/static/functions-aggregate.html

Dans l'implémentation actuelle, l'ordre de l'entrée n'est en principe pas spécifié. Cependant, fournir les valeurs d'entrée à partir d'une sous-requête triée fonctionnera généralement. Par exemple:

SELECT xmlagg (x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;

Donc, dans votre cas, vous écririez:

SELECT
array_to_string(array_agg(animal_name),';') animal_names,
array_to_string(array_agg(animal_type),';') animal_types
FROM (SELECT animal_name, animal_type FROM animals) AS x;

L'entrée de array_agg ne serait alors pas ordonnée mais ce serait la même chose dans les deux colonnes. Et si vous le souhaitez, vous pouvez ajouter une ORDER BYclause à la sous-requête.

UlfR
la source
337

Utilisez un ORDER BY, comme cet exemple du manuel :

SELECT array_agg(a ORDER BY b DESC) FROM table;
Frank Heikens
la source
42
Remarque: ORDER BYdans array_aggest introduit dans PostgreSQL 9
UlfR
6
Bien mieux que la réponse acceptée en supposant PostgreSQL 9+.
Erik
1
Pourriez-vous s'il vous plaît donner un échantillon avec ORDER BY pour sélectionner: SELECT array_agg (animal_name), array_agg (animal_type) FROM animals; ?
Grigory Kislin
10
Notez que cela ne fonctionne pas pourarray_agg(DISTINCT a ORDER BY b)
cerd
1
Lors de l'utilisation pour plusieurs colonnes, vous devez ajouter des parenthèses:array_agg((a, b, c) ORDER BY b)
bennos