Ordine array_agg PostgreSQL


107

Tabella "animali":

animal_name animal_type
Tom         Cat
Jerry       Mouse
Kermit      Frog

Query:

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

Risultato atteso:

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

Posso essere sicuro che l'ordine nella prima funzione di aggregazione sarà sempre lo stesso della seconda. Voglio dire che non vorrei ottenere:

Tom;Jerry;Kermit, Frog;Mouse,Cat

7
Se sei su 9.0 puoi sostituire le chiamate nidificate con una singolastring_agg()
a_horse_with_no_name

Risposte:


27

Se utilizzi una versione PostgreSQL <9.0, allora:

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

Nell'attuale implementazione, l'ordine dell'input è in linea di principio non specificato. Tuttavia, fornire i valori di input da una sottoquery ordinata di solito funzionerà. Per esempio:

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

Quindi nel tuo caso scriveresti:

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'input per array_agg sarebbe quindi non ordinato ma sarebbe lo stesso in entrambe le colonne. E se vuoi puoi aggiungere una ORDER BYclausola alla sottoquery.


331

Usa un ORDER BY, come questo esempio dal manuale :

SELECT array_agg(a ORDER BY b DESC) FROM table;

42
Nota: ORDER BYin array_aggè introdotto in PostgreSQL 9
UlfR

6
Molto meglio della risposta accettata assumendo PostgreSQL 9+.
Erik

1
Potresti fornire un esempio con ORDER BY per selezionare: SELECT array_agg (animal_name), array_agg (animal_type) FROM animals; ?
Grigory Kislin

9
Nota che questo non funziona perarray_agg(DISTINCT a ORDER BY b)
cerd

1
Quando si utilizza per più colonne è necessario aggiungere parentesi:array_agg((a, b, c) ORDER BY b)
bennos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.