PostgreSQL 9.0 ou posterior:
Postgres moderno (desde 2010) tem o
string_agg(expression, delimiter)
função que fará exatamente o que o solicitante estava procurando:SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
O Postgres 9 também adicionou a capacidade de especificar um
ORDER BY
cláusula em qualquer expressão agregada; caso contrário, você terá que ordenar todos os seus resultados ou lidar com uma ordem indefinida. Então agora você pode escrever:SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (em 2009) introduziu a função agregada
array_agg(expression)
que coleta os valores em uma matriz. Então array_to_string()
pode ser usado para dar o resultado desejado:SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.xe anterior:
Quando esta questão foi colocada originalmente, não havia função agregada interna para concatenar strings. A implementação personalizada mais simples (sugerida por Vajda Gabo neste post da lista de discussão, entre muitos outros) é usar o
textcat
embutido função (que está por trás do ||
operador):CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Aqui está o
CREATE AGGREGATE
documentação. Isso simplesmente cola todas as cordas juntas, sem separador. Para obter um ", " inserido entre eles sem tê-lo no final, você pode querer fazer sua própria função de concatenação e substituí-la pelo "textcat" acima. Aqui está um que montei e testei em 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 versão produzirá uma vírgula mesmo que o valor na linha seja nulo ou vazio, então você obtém uma saída assim:
a, b, c, , e, , g
Se você preferir remover vírgulas extras para gerar isso:
a, b, c, e, g
Em seguida, adicione um
ELSIF
verifique a função assim: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;