Ordem array_agg PostgreSQL

106

Tabela 'animais':

animal_name animal_type
Tom         Cat
Jerry       Mouse
Kermit      Frog

Inquerir:

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

Resultado esperado:

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

Posso ter certeza de que a ordem na primeira função de agregação será sempre a mesma que na segunda. Quer dizer, eu não gostaria de obter:

Tom;Jerry;Kermit, Frog;Mouse,Cat
Olo
fonte
7
Se você estiver no 9.0, você pode substituir as chamadas aninhadas por um únicostring_agg()
a_horse_with_no_name

Respostas:

27

Se você estiver em uma versão PostgreSQL <9.0, então:

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

Na implementação atual, a ordem da entrada não é, em princípio, especificada. Fornecer os valores de entrada de uma subconsulta classificada geralmente funcionará, no entanto. Por exemplo:

SELECT xmlagg (x) FROM (SELECT x FROM teste ORDER BY y DESC) Guia AS;

Então, no seu caso, você escreveria:

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;

A entrada para array_agg seria então desordenada, mas seria a mesma em ambas as colunas. E se quiser, você pode adicionar uma ORDER BYcláusula à subconsulta.

UlfR
fonte
330

Use um ORDER BY, como este exemplo do manual :

SELECT array_agg(a ORDER BY b DESC) FROM table;
Frank Heikens
fonte
41
Nota: ORDER BYin array_aggé apresentado no PostgreSQL 9
UlfR
6
Muito melhor do que a resposta aceita assumindo PostgreSQL 9+.
Erik
1
Você poderia dar uma amostra com ORDER BY para selecionar: SELECT array_agg (animal_name), array_agg (animal_type) FROM animals; ?
Grigory Kislin
8
Observe que isso não funciona paraarray_agg(DISTINCT a ORDER BY b)
2016
1
Ao usar para várias colunas, você deve adicionar parênteses:array_agg((a, b, c) ORDER BY b)
bennos