PostgreSQL 9.0 o posterior:
Postgres moderno (desde 2010) tiene el string_agg(expression, delimiter)
función que hará exactamente lo que estaba buscando el autor de la pregunta:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 también agregó la capacidad de especificar un ORDER BY
cláusula en cualquier expresión agregada; de lo contrario, debe ordenar todos sus resultados o tratar con un orden indefinido. Así que ahora puedes escribir:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (en 2009) introdujo la función agregada array_agg(expression)
que recopila los valores en una matriz. Entonces array_to_string()
se puede utilizar para dar el resultado deseado:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x y anteriores:
Cuando se planteó originalmente esta pregunta, no había una función agregada incorporada para concatenar cadenas. La implementación personalizada más simple (sugerida por Vajda Gabo en esta publicación de la lista de correo, entre muchas otras) es usar el textcat
incorporado función (que se encuentra detrás de ||
operador):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Aquí está el CREATE AGGREGATE
documentación.
Esto simplemente pega todas las cuerdas juntas, sin separador. Para obtener un "," insertado entre ellos sin tenerlo al final, es posible que desee crear su propia función de concatenación y sustituirla por el "textcat" anterior. Aquí hay uno que armé y probé el 8.3.12:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
Esta versión generará una coma incluso si el valor en la fila es nulo o está vacío, por lo que obtendrá un resultado como este:
a, b, c, , e, , g
Si prefiere eliminar las comas adicionales para generar esto:
a, b, c, e, g
Luego agregue un ELSIF
verifique la función de esta manera:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;