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