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