2010-08-11 22 views
17

Tengo una tabla en postgresql. En la siguiente tabla "animales" van a hacer para explicar mi problema:Ordenar un agregado de texto creado con array_agg en postgresql

name 
------ 
tiger 
cat 
dog 

Ahora estoy usando la siguiente consulta:

SELECT 
    array_to_string(array_agg("name"), ', ') 
FROM 
    animals; 

El resultado es: "tigre, gato, perro". Pero me gustaría ordenar el agregado, antes de que se convierta en una cadena. Así que este es el resultado que estoy esperando para:

"cat, dog, tiger". 

Entonces, ¿cómo puedo ordenar una matriz de cadenas en PostgreSQL 8.4 antes de convertirlo en una cadena. ORDER BY en la fila "nombre" no funciona y la función de clasificación integrada procesa solo valores enteros.

Cualquiera es una buena idea, ¿cómo resolver esto en SQL puro?

Un montón de gracias Richard

Respuesta

11

Este estará disponible en PostgreSQL 9.0:

http://www.postgresql.org/docs/9.0/static/release-9-0.html, Sección E.1.3.6.1. Agregados

Mientras tanto, se podría hacer algo como esto que puede resolver el problema (aunque torpe):

SELECT array_agg(animal_name) 
FROM (
    SELECT "name" AS animal_name 
    FROM animals 
    ORDER BY "name" 
) AS sorted_animals; 
+0

¡Esto servirá! Y muy feliz de saber que se implementará en 9.0. – Richard

0

¿Ha intentado utilizar generate_series() en la matriz, y luego hacer un SELECT...ORDER BY en ese resultado (o simplemente nido dentro de la SELECT) antes de convertirlo en una cadena?

+0

acabo anidados. La subselección hizo la magia que necesitaba. – Richard

3

Aunque la respuesta de Matthew Wood es mejor para su caso, aquí es una manera de ordenar matrices en PostgreSQL 8.4 o superior:

SELECT array(
    SELECT unnest(array[3,2,1]) AS x ORDER BY x 
); 

conociendo la array y unnest funciones puede ser útil, ya que también le permite hacer cosas como "map" sobre una matriz:

SELECT array(
    SELECT x*x FROM (SELECT unnest(array[1,2,3]) AS x) as subquery 
); 

Nuevamente, esto puede ser suyo por el precio de PostgreSQL 8.4.

+0

Una gran solución que tendré en cuenta. Muchas gracias. – Richard

39

Para PostgreSQL 9.0 and later, puede utilizar una cláusula ORDER BY en una expresión agregada:

SELECT 
    array_to_string(array_agg(name ORDER BY name), ', ') 
FROM 
    animals; 

Además, para su propósito específico, puede utilizar string_agg para simplificar su consulta:

SELECT 
    string_agg(name, ', ' ORDER BY name) 
FROM 
    animals; 
+0

¡Gracias por la pista! – Richard

0

embargo, para la versión 8.4, utilizando la solución sugerida por Matthew Wood, si necesita hacer una agrupación en la consulta externa, la consulta interna también debe ordenarse para que la ordenación sea coherente.

SELECT family, array_agg(animal_name) 
FROM (
    SELECT family, "name" AS animal_name 
    FROM animals 
    ORDER BY family, "name" 
) AS sorted_animals 
group by family; 
Cuestiones relacionadas