sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo devolver los resultados de la consulta como una lista separada por comas en SQL Server – STRING_AGG()

A partir de SQL Server 2017, ahora puede hacer que los resultados de su consulta aparezcan como una lista. Esto significa que puede hacer que su conjunto de resultados aparezca como una lista separada por comas, una lista separada por espacios o cualquier separador que elija usar.

Si bien es cierto que podía lograr este mismo efecto antes de SQL Server 2017, era un poco complicado.

Transact-SQL ahora tiene el STRING_AGG() función, que concatena los valores de expresiones de cadena y coloca valores separadores entre ellos. Esto funciona de la misma manera que GROUP_CONCAT() de MySQL función.

Este artículo proporciona ejemplos que demuestran el T-SQL STRING_AGG() función.

Datos de muestra

Primero, aquí hay algunos datos de muestra.

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   

Ejemplo:lista separada por comas

Entonces podríamos tomar los datos anteriores y usar el STRING_AGG() función para enumerar todos los nombres de tareas en una gran lista separada por comas.

Así:

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

Resultado:

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

Por supuesto, no necesariamente tiene que estar separado por una coma. Se puede separar por cualquier expresión de NVARCHAR o VARCHAR tipo, y puede ser un literal o una variable.

Ejemplo:combinar columnas

También podríamos usar el CONCAT() función para combinar dos campos juntos, separados por su propio separador.

Ejemplo:

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

Ejemplo:valores nulos

Si su conjunto de resultados contiene valores nulos, esos valores se ignoran y no se agrega el separador correspondiente.

Si esto no es adecuado, puede proporcionar un valor para los valores nulos utilizando ISNULL() y pasando el valor que le gustaría usar cada vez que se encuentre un valor nulo. Hacer esto asegura que aún obtenga un resultado cuando una fila contiene un valor nulo.

Por ejemplo, considere la siguiente consulta y conjunto de resultados:

SELECT TaskCode 
FROM Tasks;

Resultado:

TaskCode
--------
cat123  
null    
null    
pnt456  
rof789  
null    

Podemos ver que hay tres valores nulos dentro del conjunto de resultados.

Si ejecutamos esto a través de STRING_AGG() función, obtenemos esto:

SELECT STRING_AGG(TaskCode, ', ') 
FROM Tasks;

Resultado:

cat123, pnt456, rof789

Sin embargo, si usamos el ISNULL() para proporcionar un marcador de posición para cualquier valor nulo, obtenemos esto:

SELECT STRING_AGG(ISNULL(TaskCode, 'N/A'), ', ') 
FROM Tasks;

Resultado:

cat123, N/A, N/A, pnt456, rof789, N/A

Ejemplo:resultados agrupados

También puede usar el STRING_AGG() función al agrupar su conjunto de resultados. Por ejemplo, es posible que desee una lista de álbumes agrupados por artista.

Para demostrar esto, imagina una base de datos con dos tablas; Artists y Albums . Hay una relación de uno a muchos entre estas tablas. Para cada artista, puede haber muchos álbumes.

Entonces, una consulta regular que une ambas tablas podría verse así:

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 puede ver, si un artista tiene más de un álbum, el nombre del artista aparece varias veces, una para cada álbum.

Pero podemos usar STRING_AGG() para cambiar esto para que enumeremos a cada artista solo una vez, seguido de una lista separada por comas de los álbumes que han lanzado:

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                        

Ejemplo:ordenar los resultados

Puede utilizar una cláusula de orden para ordenar los resultados dentro del grupo concatenado. Esto se hace con el WITHIN GROUP cláusula. Al usar esta cláusula, especifica el orden con ORDER BY seguido de ASC (para ascender) o DESC (para descender).

Ejemplo:

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