Considere uma tabela de banco de dados contendo nomes, com três linhas:
Peter
Paul
Mary
Existe uma maneira fácil de transformar isso em uma única sequência de Peter, Paul, Mary
?
Considere uma tabela de banco de dados contendo nomes, com três linhas:
Peter
Paul
Mary
Existe uma maneira fácil de transformar isso em uma única sequência de Peter, Paul, Mary
?
Respostas:
Se você estiver no SQL Server 2017 ou Azure, consulte Mathieu Renda reply .
Eu tive um problema semelhante ao tentar juntar duas tabelas com relacionamentos um para muitos. No SQL 2005, descobri que o
XML PATH
método pode lidar com a concatenação das linhas com muita facilidade.Se houver uma tabela chamada
STUDENTS
O resultado que eu esperava era:
Eu usei o seguinte
T-SQL
:Você pode fazer a mesma coisa de uma maneira mais compacta se puder concaturar as vírgulas no início e usar
substring
para pular a primeira para não precisar fazer uma subconsulta:fonte
<
ou&
. Veja o comentário de @ BenHinman.FOR XML PATH ('')
. Isso significa que não deve ser considerado confiável, pois qualquer patch ou atualização pode alterar a forma como isso funciona. Basicamente, depende de um recurso obsoleto.FOR XML
se destina a gerar XML, não concatenar seqüências arbitrárias. É por isso que escapa&
,<
e>
aos códigos de entidade XML (&
,<
,>
). Presumo que também irá escapar"
e'
para"
e'
em atributos também. É nãoGROUP_CONCAT()
,string_agg()
,array_agg()
,listagg()
, etc., mesmo se você pode tipo de fazê-lo fazer isso. Nós deve estar gastando nosso tempo exigindo Microsoft implementar uma função adequada.string_agg
v.Next. e tudo isso pode ir embora.Use
COALESCE
:Apenas uma explicação (já que esta resposta parece ter visualizações relativamente regulares):
1) Não há necessidade de inicializar
@Names
com um valor de sequência vazio.2) Não é necessário retirar um separador extra no final.
@Names
NULL após essa linha e a próxima linha começará novamente como uma string vazia novamente. soluções:ou:
Dependendo do comportamento desejado (a primeira opção filtra apenas NULL s, a segunda opção os mantém na lista com uma mensagem de marcador [substitua 'N / A' pelo que for apropriado para você)).
fonte
SQL Server 2017 ou superior e SQL Azure: STRING_AGG
Começando com a próxima versão do SQL Server, podemos finalmente concatenar as linhas sem precisar recorrer a nenhuma variável ou bruxaria XML.
STRING_AGG (Transact-SQL)
Sem agrupamento
Com o agrupamento:
Com agrupamento e sub-classificação
fonte
Um método ainda não mostrado por meio do
XML
data()
comando no MS SQL Server é:Suponha que a tabela chamada NameList com uma coluna chamada FName,
retorna:
Somente a vírgula extra deve ser tratada.
Editar: conforme adotado no comentário de @ NReilingh, você pode usar o seguinte método para remover a vírgula à direita. Supondo os mesmos nomes de tabela e coluna:
fonte
+ ', '
ele ainda adiciona um espaço único entre todos os elementos concatenados.SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
No SQL Server 2005
No SQL Server 2016
você pode usar o sintaxe FOR JSON
ie
E o resultado se tornará
Isso funcionará mesmo que seus dados contenham caracteres XML inválidos
o
'"},{"_":"'
é seguro porque se você contém dados'"},{"_":"',
eles serão escapados para"},{\"_\":\"
Você pode substituir
', '
por qualquer separador de cadeiaE no SQL Server 2017, Banco de Dados SQL do Azure
Você pode usar a nova função STRING_AGG
fonte
<
,>
,&
, etc, queFOR XML PATH('')
vai escapar automaticamente.No MySQL, há uma função, GROUP_CONCAT () , que permite concatenar os valores de várias linhas. Exemplo:
fonte
SEPARATOR '", "'
vou sentir falta de alguns caracteres no final da última entrada. por que isso pode acontecer?CHAR
, você precisa convertê-la, por exemplo, viaGROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')
2) se você tiver muitos valores chegando, você deve aumentar o valorgroup_concat_max_len
como está escrito em stackoverflow.com/a/1278210/1498405Use COALESCE - Saiba mais aqui
Por exemplo:
Em seguida, escreva o código abaixo no servidor sql,
A saída seria:
fonte
Declare @Numbers AS Nvarchar(MAX)
e funcionou bem. Você pode explicar por que recomenda não usá-lo, por favor?As matrizes do Postgres são incríveis. Exemplo:
Crie alguns dados de teste:
Agregue-os em uma matriz:
Converta a matriz em uma cadeia de caracteres delimitada por vírgula:
FEITO
Desde o PostgreSQL 9.0, é ainda mais fácil .
fonte
select array_to_string(array_agg(name||'('||id||')'
O Oracle 11g Release 2 suporta a função LISTAGG. Documentação aqui .
Atenção
Cuidado ao implementar esta função se houver possibilidade de a sequência resultante ter mais de 4000 caracteres. Isso lançará uma exceção. Se for esse o caso, você precisará manipular a exceção ou rolar sua própria função que evita que a sequência de caracteres junte mais de 4000 caracteres.
fonte
LISTAGG
funciona perfeito! Basta ler o documento vinculado aqui.wm_concat
removido da versão 12c em diante.No SQL Server 2005 e posterior, use a consulta abaixo para concatenar as linhas.
fonte
<
ou&
.Como não tenho acesso a um SQL Server em casa, acho que tenho a sintaxe aqui, mas é mais ou menos:
fonte
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
SELECT @names = @names + ISNULL(' ' + Name, '')
Uma solução CTE recursiva foi sugerida, mas nenhum código foi fornecido. O código abaixo é um exemplo de uma CTE recursiva. Observe que, embora os resultados correspondam à pergunta, os dados não correspondem exatamente à descrição fornecida, pois presumo que você realmente queira fazer isso em grupos de linhas, nem todas as linhas da tabela. A alteração para corresponder a todas as linhas da tabela é deixada como um exercício para o leitor.
fonte
name
coluna em uma sequência separada por vírgula por 4 grupos deid
s. À primeira vista, acho que isso é mais trabalhoso do que a maioria das outras soluções para o SQL Server.A partir do PostgreSQL 9.0, isso é bastante simples:
Nas versões anteriores à 9.0,
array_agg()
pode ser usado como mostrado por hgmnzfonte
SELECT string_agg(non_text_type::text, ',') FROM table
varchar
ouchar
Você precisa criar uma variável que mantenha seu resultado final e selecione-o, assim.
Solução mais fácil
fonte
No SQL Server vNext, isso será incorporado com a função STRING_AGG, leia mais sobre isso aqui: https://msdn.microsoft.com/en-us/library/mt790580.aspx
fonte
O uso de XML me ajudou a obter linhas separadas por vírgulas. Para a vírgula extra, podemos usar a função de substituição do SQL Server. Em vez de adicionar uma vírgula, o uso do AS 'data ()' concatenará as linhas com espaços, que posteriormente poderão ser substituídos por vírgulas conforme a sintaxe escrita abaixo.
fonte
Uma solução pronta para uso, sem vírgulas extras:
Uma lista vazia resultará em valor NULL. Geralmente, você inserirá a lista em uma coluna da tabela ou variável de programa: ajuste o comprimento máximo de 255 conforme sua necessidade.
(Diwakar e Jens Frandsen forneceram boas respostas, mas precisam de melhorias.)
fonte
', '
por','
se você não quiser o espaço extra.Aqui está uma amostra:
fonte
Isso coloca a vírgula dispersa no início.
No entanto, se você precisar de outras colunas, ou para CSV uma tabela filha, precisará agrupá-la em um campo escalar definido pelo usuário (UDF).
Você também pode usar o caminho XML como uma subconsulta correlacionada na cláusula SELECT (mas precisaria esperar até voltar ao trabalho porque o Google não faz coisas em casa :-)
fonte
Com as outras respostas, a pessoa que está lendo a resposta deve estar ciente de uma tabela de domínio específica, como veículo ou aluno. A tabela deve ser criada e preenchida com dados para testar uma solução.
Abaixo está um exemplo que usa a tabela "Information_Schema.Columns" do SQL Server. Ao usar esta solução, nenhuma tabela precisa ser criada ou dados adicionados. Este exemplo cria uma lista separada por vírgula de nomes de colunas para todas as tabelas no banco de dados.
fonte
Para bancos de dados Oracle, consulte esta pergunta: Como várias linhas podem ser concatenadas em uma no Oracle sem criar um procedimento armazenado?
A melhor resposta parece ser de @Emmanuel, usando a função LISTAGG () interna, disponível no Oracle 11g Release 2 e posterior.
como o @ user762952 apontou e de acordo com a documentação da Oracle http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , a função WM_CONCAT () também é uma opção. Parece estável, mas a Oracle recomenda explicitamente não usá-lo para qualquer aplicativo SQL, portanto, use por seu próprio risco.
Fora isso, você terá que escrever sua própria função; o documento Oracle acima tem um guia sobre como fazer isso.
fonte
Para evitar valores nulos, você pode usar CONCAT ()
fonte
Eu realmente gostei da elegância da resposta de Dana . Só queria torná-lo completo.
fonte
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Names
, em seguida, você não tem de truncar-lo depois.Esta resposta exigirá algum privilégio no servidor para funcionar.
Assemblies são uma boa opção para você. Existem muitos sites que explicam como criá-lo. O que eu acho que é muito bem explicado é este um
Se você quiser, eu já criei o assembly e é possível baixar a DLL aqui .
Depois de baixá-lo, você precisará executar o seguinte script no seu SQL Server:
Observe que o caminho para a montagem pode estar acessível ao servidor. Como você executou todas as etapas com êxito, você pode usar a função como:
Espero que ajude!!!
fonte
Exemplo completo do MySQL:
Temos usuários que podem ter muitos dados e queremos ter uma saída, onde podemos ver todos os dados dos usuários em uma lista:
Resultado:
Configuração da tabela:
Inquerir:
fonte
Eu costumo usar select assim para concatenar seqüências de caracteres no SQL Server:
fonte
Se você deseja lidar com nulos, pode fazê-lo adicionando uma cláusula where ou adicione outro COALESCE ao redor da primeira.
fonte
Isso funcionou para mim ( SqlServer 2016 ):
Aqui está a fonte: https://www.mytecbits.com/
E uma solução para o MySql (já que esta página aparece no Google para MySql)
De documentação do MySql
fonte
No Oracle, é
wm_concat
. Acredito que esta função esteja disponível na versão 10g e superior.fonte
Isso também pode ser útil
retorna
fonte