sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo concatenar cadenas de un campo de cadena en una consulta 'agrupar por' de PostgreSQL?

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;