Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como retornar os resultados da consulta como uma lista separada por vírgulas no SQL Server – STRING_AGG()


A partir do SQL Server 2017, agora você pode fazer com que os resultados da consulta apareçam como uma lista. Isso significa que você pode fazer com que seu conjunto de resultados apareça como uma lista separada por vírgulas, uma lista separada por espaços ou qualquer separador que você escolher usar.

Embora seja verdade que você poderia obter esse mesmo efeito antes do SQL Server 2017, era um pouco complicado.

Transact-SQL agora tem o STRING_AGG() função, que concatena os valores de expressões de string e coloca valores separadores entre eles. Isso funciona da mesma maneira que o GROUP_CONCAT() do MySQL função.

Este artigo fornece exemplos que demonstram o T-SQL STRING_AGG() função.


Dados de amostra


Primeiro, aqui estão alguns dados de exemplo.
SELECT TaskId, TaskName 
FROM Tasks;

Resultado:
TaskId  TaskName    
------  ------------
1       Feed cats   
2       Water dog   
3       Feed garden 
4       Paint carpet
5       Clean roof  
6       Feed cats   

Exemplo - Lista separada por vírgulas


Assim, podemos pegar os dados acima e usar o STRING_AGG() função para listar todos os nomes de tarefas em uma grande lista separada por vírgulas.

Assim:
SELECT STRING_AGG(TaskName, ', ') 
FROM Tasks;

Resultado:
Feed cats, Water dog, Feed garden, Paint carpet, Clean roof, Feed cats   

Claro, não precisa necessariamente ser separado por uma vírgula. Ele pode ser separado por qualquer expressão de NVARCHAR ou VARCHAR tipo, e pode ser um literal ou uma variável.

Exemplo – Combinando Colunas


Também podemos usar o CONCAT() função para combinar dois campos juntos, separados por seu próprio separador.

Exemplo:
SELECT STRING_AGG(CONCAT(TaskId, ') ', TaskName), ' ') 
FROM Tasks;

Resultado:
1) Feed cats 2) Water dog 3) Feed garden 4) Paint carpet 5) Clean roof 6) Feed cats

Exemplo - Valores Nulos


Se o conjunto de resultados contiver valores nulos, esses valores serão ignorados e um separador correspondente não será adicionado.

Se isso não for adequado, você pode fornecer um valor para valores nulos usando o ISNULL() função e passando o valor que você gostaria de usar sempre que um valor nulo for encontrado. Isso garante que você ainda obtenha um resultado quando uma linha contiver um valor nulo.

Por exemplo, considere a seguinte consulta e conjunto de resultados:
SELECT TaskCode 
FROM Tasks;

Resultado:
TaskCode
--------
cat123  
null    
null    
pnt456  
rof789  
null    

Podemos ver que existem três valores nulos no conjunto de resultados.

Se executarmos isso através do STRING_AGG() função, obtemos isso:
SELECT STRING_AGG(TaskCode, ', ') 
FROM Tasks;

Resultado:
cat123, pnt456, rof789

No entanto, se usarmos o ISNULL() função para fornecer um espaço reservado para quaisquer valores nulos, obtemos isso:
SELECT STRING_AGG(ISNULL(TaskCode, 'N/A'), ', ') 
FROM Tasks;

Resultado:
cat123, N/A, N/A, pnt456, rof789, N/A

Exemplo – Resultados Agrupados


Você também pode usar o STRING_AGG() função ao agrupar seu conjunto de resultados. Por exemplo, você pode querer uma lista de álbuns agrupados por artista.

Para demonstrar isso, imagine um banco de dados com duas tabelas; Artists e Albums . Há uma relação de um para muitos entre essas tabelas. Para cada artista, pode haver muitos álbuns.

Portanto, uma consulta regular juntando as duas tabelas pode ser algo assim:
USE Music;
SELECT ar.ArtistName,
	al.AlbumName
FROM Artists ar
INNER JOIN Albums al
ON ar.ArtistId = al.ArtistId;

Resultado:
ArtistName                 AlbumName               
-------------------------  ------------------------
Iron Maiden                Powerslave              
AC/DC                      Powerage                
Jim Reeves                 Singing Down the Lane   
Devin Townsend             Ziltoid the Omniscient  
Devin Townsend             Casualties of Cool      
Devin Townsend             Epicloud                
Iron Maiden                Somewhere in Time       
Iron Maiden                Piece of Mind           
Iron Maiden                Killers                 
Iron Maiden                No Prayer for the Dying 
The Script                 No Sound Without Silence
Buddy Rich                 Big Swing Face          
Michael Learns to Rock     Blue Night              
Michael Learns to Rock     Eternity                
Michael Learns to Rock     Scandinavia             
Tom Jones                  Long Lost Suitcase      
Tom Jones                  Praise and Blame        
Tom Jones                  Along Came Jones        
Allan Holdsworth           All Night Wrong         
Allan Holdsworth           The Sixteen Men of Tain 

Como você pode ver, se um artista tiver mais de um álbum, o nome do artista será listado várias vezes – uma vez para cada álbum.

Mas podemos usar STRING_AGG() para alterar isso para que listemos cada artista apenas uma vez, seguido por uma lista separada por vírgulas dos álbuns que eles lançaram:
USE Music;
SELECT ar.ArtistName,
	STRING_AGG(al.AlbumName, ', ')
FROM Artists ar
INNER JOIN Albums al
ON ar.ArtistId = al.ArtistId
GROUP BY ArtistName;

Resultado:
ArtistName                                                                                               
-------------------------  ------------------------------------------------------------------------------
AC/DC                      Powerage                                                                      
Allan Holdsworth           All Night Wrong, The Sixteen Men of Tain                                      
Buddy Rich                 Big Swing Face                                                                
Devin Townsend             Ziltoid the Omniscient, Casualties of Cool, Epicloud                          
Iron Maiden                Powerslave, Somewhere in Time, Piece of Mind, Killers, No Prayer for the Dying
Jim Reeves                 Singing Down the Lane                                                         
Michael Learns to Rock     Blue Night, Eternity, Scandinavia                                             
The Script                 No Sound Without Silence                                                      
Tom Jones                  Long Lost Suitcase, Praise and Blame, Along Came Jones                        

Exemplo – Ordenando os Resultados


Você pode usar uma cláusula order para ordenar os resultados no grupo concatenado. Isso é feito com o WITHIN GROUP cláusula. Ao usar esta cláusula, você especifica o pedido com ORDER BY seguido por ASC (para ascendente) ou DESC (para descer).

Exemplo:
USE Music;
SELECT ar.ArtistName,
	STRING_AGG(al.AlbumName, ', ') WITHIN GROUP (ORDER BY al.AlbumName DESC)
FROM Artists ar
INNER JOIN Albums al
ON ar.ArtistId = al.ArtistId
GROUP BY ArtistName;

Resultado:
ArtistName                                                                                               
-------------------------  ------------------------------------------------------------------------------
AC/DC                      Powerage                                                                      
Allan Holdsworth           The Sixteen Men of Tain, All Night Wrong                                      
Buddy Rich                 Big Swing Face                                                                
Devin Townsend             Ziltoid the Omniscient, Epicloud, Casualties of Cool                          
Iron Maiden                Somewhere in Time, Powerslave, Piece of Mind, No Prayer for the Dying, Killers
Jim Reeves                 Singing Down the Lane                                                         
Michael Learns to Rock     Scandinavia, Eternity, Blue Night                                             
The Script                 No Sound Without Silence                                                      
Tom Jones                  Praise and Blame, Long Lost Suitcase, Along Came Jones