¿Equivalente a Postgresql GROUP_CONCAT?

Resuelto TwixxyKit asked hace 14 años • 9 respuestas

Tengo una tabla y me gustaría extraer una fila por identificación con valores de campo concatenados.

En mi mesa por ejemplo tengo esto:

TM67 | 4  | 32556
TM67 | 9  | 98200
TM67 | 72 | 22300
TM99 | 2  | 23009
TM99 | 3  | 11200

Y me gustaría generar:

TM67 | 4,9,72 | 32556,98200,22300
TM99 | 2,3    | 23009,11200

En MySQL pude usar la función agregada GROUP_CONCAT, pero eso no parece funcionar aquí... ¿Existe un equivalente para PostgreSQL u otra forma de lograr esto?

TwixxyKit avatar Apr 01 '10 21:04 TwixxyKit
Aceptado

Desde la versión 9.0 esto es aún más fácil:

SELECT id, 
       string_agg(some_column, ',')
FROM the_table
GROUP BY id
 avatar Jan 10 '2012 12:01

Este es probablemente un buen punto de partida (solo versión 8.4+):

SELECT id_field, array_agg(value_field1), array_agg(value_field2)
FROM data_table
GROUP BY id_field

array_agg devuelve una matriz, pero puede TRANSMITIRla a texto y editarla según sea necesario (consulte las aclaraciones a continuación).

Antes de la versión 8.4, debes definirlo tú mismo antes de usarlo:

CREATE AGGREGATE array_agg (anyelement)
(
    sfunc = array_append,
    stype = anyarray,
    initcond = '{}'
);

(parafraseado de la documentación de PostgreSQL)

Aclaraciones:

  • El resultado de convertir una matriz en texto es que la cadena resultante comienza y termina con llaves. Esos aparatos deben retirarse mediante algún método, si no se desean.
  • La conversión de ANYARRAY a TEXT simula mejor la salida CSV, ya que los elementos que contienen comas incrustadas están entre comillas dobles en la salida en estilo CSV estándar. Ni array_to_string() ni string_agg() (la función "group_concat" agregada en 9.1) citan cadenas con comas incrustadas, lo que da como resultado un número incorrecto de elementos en la lista resultante.
  • La nueva función 9.1 string_agg() NO convierte los resultados internos a TEXTO primero. Entonces "string_agg(value_field)" generaría un error si value_field es un número entero. Se requeriría "string_agg(value_field::text)". El método array_agg() requiere solo una conversión después de la agregación (en lugar de una conversión por valor).
Matthew Wood avatar Apr 01 '2010 14:04 Matthew Wood
SELECT array_to_string(array(SELECT a FROM b),', ');

Lo haré también.

genobis avatar Dec 17 '2010 09:12 genobis