PostgreSQL array_agg Reihenfolge

106

Tabelle 'Tiere':

animal_name animal_type
Tom         Cat
Jerry       Mouse
Kermit      Frog

Abfrage:

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

Erwartetes Ergebnis:

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

Kann ich sicher sein, dass die Reihenfolge in der ersten Aggregatfunktion immer dieselbe ist wie in der zweiten. Ich meine, ich möchte nicht bekommen:

Tom;Jerry;Kermit, Frog;Mouse,Cat
Olo
quelle
7
Wenn Sie auf 9.0 sind, können Sie die verschachtelten Anrufe durch ein einzelnes ersetzenstring_agg()
a_horse_with_no_name

Antworten:

27

Wenn Sie eine PostgreSQL-Version <9.0 verwenden, gilt Folgendes:

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

In der aktuellen Implementierung ist die Reihenfolge der Eingabe im Prinzip nicht spezifiziert. Die Angabe der Eingabewerte aus einer sortierten Unterabfrage funktioniert jedoch normalerweise. Beispielsweise:

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

In Ihrem Fall würden Sie also schreiben:

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;

Die Eingabe in das array_agg wäre dann ungeordnet, aber in beiden Spalten gleich. Und wenn Sie ORDER BYmöchten, können Sie der Unterabfrage eine Klausel hinzufügen.

UlfR
quelle
327

Verwenden Sie ein ORDER BY wie in diesem Beispiel aus dem Handbuch :

SELECT array_agg(a ORDER BY b DESC) FROM table;
Frank Heikens
quelle
41
Hinweis: ORDER BYin array_aggwird in PostgreSQL 9
UlfR
6
Viel besser als die akzeptierte Antwort unter der Annahme von PostgreSQL 9+.
Erik
1
Könnten Sie bitte ein Beispiel mit ORDER BY für die Auswahl geben: SELECT array_agg (animal_name), array_agg (animal_type) FROM animal; ?
Grigory Kislin
8
Beachten Sie, dass dies nicht funktioniert fürarray_agg(DISTINCT a ORDER BY b)
cerd
1
Wenn Sie für mehrere Spalten verwenden, müssen Sie Klammern hinzufügen:array_agg((a, b, c) ORDER BY b)
Bennos