Eu estou procurando uma maneira de concatenar as seqüências de caracteres de um campo dentro de um grupo por consulta. Então, por exemplo, eu tenho uma tabela:
ID COMPANY_ID EMPLOYEE
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave
e eu queria agrupar por company_id para obter algo como:
COMPANY_ID EMPLOYEE
1 Anna, Bill
2 Carol, Dave
Há uma função interna no mySQL para fazer isso group_concat
Respostas:
PostgreSQL 9.0 ou posterior:
Versões recentes do Postgres (desde o final de 2010) têm a
string_agg(expression, delimiter)
função que fará exatamente o que a pergunta pediu, até mesmo permitindo que você especifique a string delimitadora:O Postgres 9.0 também adicionou a capacidade de especificar uma
ORDER BY
cláusula em qualquer expressão agregada ; caso contrário, o pedido não será definido. Agora você pode escrever:Ou de fato:
PostgreSQL 8.4 ou posterior:
O PostgreSQL 8.4 (em 2009) introduziu a função agregada
array_agg(expression)
que concatena os valores em uma matriz. Entãoarray_to_string()
pode ser usado para dar o resultado desejado:string_agg
para versões anteriores à 8.4:Caso alguém se depare com isso procurando uma correção de compatibilidade para bancos de dados anteriores à 9.0, é possível implementar tudo,
string_agg
exceto aORDER BY
cláusula.Portanto, com a definição abaixo, isso deve funcionar da mesma maneira que no DB 9.x do Postgres:
Mas este será um erro de sintaxe:
Testado no PostgreSQL 8.3.
Variações personalizadas (todas as versões do Postgres)
Antes da 9.0, não havia função agregada incorporada para concatenar seqüências de caracteres. A implementação personalizada mais simples ( sugerida por Vajda Gabo nesta postagem da lista de discussão , entre muitas outras) é usar a
textcat
função interna (que fica atrás do||
operador):Aqui está a
CREATE AGGREGATE
documentação.Isso simplesmente cola todas as cordas, sem separador. Para obter um "," inserido entre eles sem tê-lo no final, convém criar sua própria função de concatenação e substituí-la pelo "textcat" acima. Aqui está um que eu montei e testei em 8.3.12:
Esta versão produzirá uma vírgula mesmo que o valor na linha seja nulo ou vazio, para que você obtenha uma saída como esta:
Se você preferir remover vírgulas extras para gerar isso:
Em seguida, adicione uma
ELSIF
verificação à função como esta:fonte
array_to_string(array_agg(employee), ',')
?Order By
cláusula dentro da função de agregação, por exemplo,string_agg(employee, ',' Order By employee)
Que tal usar as funções de matriz incorporadas do Postgres? Pelo menos no 8.4, isso funciona imediatamente:
fonte
A partir do PostgreSQL 9.0, você pode usar a função agregada chamada string_agg . Seu novo SQL deve ser algo como isto:
fonte
Não reivindico crédito pela resposta porque a encontrei após algumas pesquisas:
O que eu não sabia é que o PostgreSQL permite que você defina suas próprias funções agregadas com CREATE AGGREGATE
Este post na lista do PostgreSQL mostra como é trivial criar uma função para fazer o que é necessário:
fonte
Como já mencionado, criar sua própria função agregada é a coisa certa a fazer. Aqui está minha função agregada de concatenação (você pode encontrar detalhes em francês ):
);
E depois use-o como:
fonte
Este último snippet da lista de anúncios pode ser interessante se você atualizar para a 8.4:
Eu vincularia aos documentos de desenvolvimento 8.4, mas eles ainda não parecem listar esse recurso.
fonte
Seguindo a resposta de Kev, usando os documentos do Postgres:
Primeiro, crie uma matriz dos elementos e use a
array_to_string
função interna.fonte
Seguindo mais uma vez o uso de uma função agregada personalizada da concatenação de cadeias: você precisa lembrar que a instrução select colocará linhas em qualquer ordem, portanto, será necessário fazer uma sub- seleção na instrução from com uma cláusula order by , e em seguida, uma seleção externa com uma cláusula group by para agregar as strings, assim:
fonte
Achei esta documentação do PostgreSQL útil: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html .
No meu caso, procurei o SQL simples para concatenar um campo com colchetes, se o campo não estiver vazio.
fonte
Use a
STRING_AGG
função para PostgreSQL e Google BigQuery SQL :fonte
De acordo com a versão PostgreSQL 9.0 e superior, você pode usar a função agregada chamada string_agg. Seu novo SQL deve ser algo como isto:
fonte
Você também pode usar a função de formatação. O que também pode implicitamente cuidar da conversão de tipo de texto, int, etc. por si só.
fonte
Estou usando o Jetbrains Rider e foi um incômodo copiar os resultados dos exemplos acima para executar novamente, porque parecia envolver tudo isso em JSON. Isso os une em uma única instrução que era mais fácil de executar
fonte
Se você estiver no Amazon Redshift, onde string_agg não é suportado, tente usar listagg.
fonte