STRING_AGG (Transact-SQL)
Aplica-se a:SQL Server 2017 (14.x) e posterior Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Azure Synapse Analytics Ponto de extremidade de análise de SQL no Microsoft FabricWarehouse no Microsoft Fabric
Concatena os valores das expressões de cadeia de caracteres e coloca os valores de separador entre eles. O separador não é adicionado ao final da cadeia de caracteres.
Convenções de sintaxe de Transact-SQL
Sintaxe
STRING_AGG ( expression , separator ) [ <order_clause> ]
<order_clause> ::=
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
Argumentos
expressão
Uma expressão de qualquer tipo. Expressões são convertidas em nvarchar ou tipos de varchar durante a concatenação. Tipos de não cadeia de caracteres são convertidos em tipo de nvarchar.
separator
Uma expressão de nvarchar ou tipo de varchar usado como separador para cadeias de caracteres concatenadas. Pode ser um literal ou uma variável.
<order_clause>
Opcionalmente, especifique a ordem dos resultados concatenados usando a cláusula WITHIN GROUP
:
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
<order_by_expression_list>
Uma lista de expressions de não constante que pode ser usada para classificar os resultados. Apenas uma
<order_by_expression_list>
é permitida por consulta. A ordem de classificação padrão é crescente.
Tipos de retorno
O tipo de retorno depende do primeiro argumento (expressão). Se o argumento de entrada for tipo de cadeia de caracteres (nvarchar, varchar), o tipo de resultado será o mesmo que o tipo de entrada. A seguinte tabela lista as conversões automáticas:
Tipo de expressão de entrada | Result |
---|---|
nvarchar(max) | nvarchar(max) |
|
|
nvarchar(1..4000) | nvarchar(4000) |
varchar(1..8000) | |
int, bigint, smallint, minúsculo, numérico, flutuante, real, bit, decimal, smallmoney, de dinheiro, datetime, datetime2 |
nvarchar(4000) |
Comentários
STRING_AGG
é uma função de agregação que usa todas as expressões de linhas e concatena-as em uma única cadeia de caracteres. Os valores de expressão são convertidos implicitamente em tipos de cadeia de caracteres e depois concatenados. A conversão implícita em cadeias de caracteres segue as regras existentes para conversões de tipo de dados. Para obter mais informações sobre conversões de tipo de dados, consulte CAST e CONVERT.
Se a expressão de entrada for tipo varchar, o separador não poderá ser tipo nvarchar.
Valores nulos são ignorados e o separador correspondente não é adicionado. Para retornar um espaço reservado para valores nulos, use a função ISNULL
, conforme demonstrado em exemplo B.
STRING_AGG
está disponível em qualquer nível de compatibilidade.
Observação
O <order_clause>
está disponível com o nível de compatibilidade do banco de dados 110 e superior.
Exemplos
Os exemplos de código Transact-SQL neste artigo usam o banco de dados de exemplo AdventureWorks2022
ou AdventureWorksDW2022
, que você pode baixar na home page Microsoft SQL Server Samples and Community Projects.
a. Gerar a lista de nomes separados em novas linhas
O exemplo a seguir gera uma lista de nomes em uma única célula de resultados, separados com retornos de carro.
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), FirstName), CHAR(13)) AS csv
FROM Person.Person;
GO
Veja a seguir o conjunto de resultados.
csv
-----------
Syed
Catherine
Kim
Kim
Kim
Hazem
...
Os valores NULL
encontrados nas células name
não são retornados no resultado.
Observação
Se estiver usando o Editor de Consultas do SQL Server Management Studio, a opção Resultados para Grade não poderá implementar o retorno de carro. Alterne para Resultados em Texto para ver o conjunto de resultados corretamente. Os Resultados em Texto são truncados para 256 caracteres por padrão. Para aumentar esse limite, altere a opção Número máximo de caracteres exibidos em cada coluna.
B. Gerar lista de nomes separados por vírgula sem valores de NULL
O exemplo a seguir substitui valores nulos por 'N/A' e retorna os nomes separados por vírgulas em uma única célula de resultados.
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), ISNULL(FirstName, 'N/A')), ',') AS csv
FROM Person.Person;
GO
Aqui está um conjunto de resultados cortado.
csv
-----
Syed,Catherine,Kim,Kim,Kim,Hazem,Sam,Humberto,Gustavo,Pilar,Pilar, ...
C. Gerar valores separados por vírgula
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), CONCAT(FirstName, ' ', LastName, '(', ModifiedDate, ')')), CHAR(13)) AS names
FROM Person.Person;
GO
Aqui está um conjunto de resultados cortado.
names
-------
Ken Sánchez (Feb 8 2003 12:00AM)
Terri Duffy (Feb 24 2002 12:00AM)
Roberto Tamburello (Dec 5 2001 12:00AM)
Rob Walters (Dec 29 2001 12:00AM)
...
Observação
Se estiver usando o Editor de Consultas do Management Studio, a opção Resultados para Grade não poderá implementar o retorno de carro. Alterne para Resultados em Texto para ver o conjunto de resultados corretamente.
D. Retornar artigos de notícias com marcas relacionadas
Imagine um banco de dados em que artigos e suas marcas sejam separados em tabelas diferentes. Um desenvolvedor deseja retornar uma linha por artigo com todas as marcas associadas. A seguinte consulta atinge este resultado:
SELECT a.articleId,
title,
STRING_AGG(tag, ',') AS tags
FROM dbo.Article AS a
LEFT OUTER JOIN dbo.ArticleTag AS t
ON a.ArticleId = t.ArticleId
GROUP BY a.articleId, title;
GO
Veja a seguir o conjunto de resultados.
articleId | título | marcas |
---|---|---|
172 |
Polls indicate close election results |
politics,polls,city council |
176 |
New highway expected to reduce congestion |
NULL |
177 |
Dogs continue to be more popular than cats |
polls,animals |
Observação
A cláusula GROUP BY
será necessária se a função STRING_AGG
não for o único item na lista SELECT
.
E. Gerar uma lista de emails por cidades
A seguinte consulta localiza os endereços de email de funcionários e agrupa-os por cidade:
USE AdventureWorks2022;
GO
SELECT TOP 10 City,
STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') AS emails
FROM Person.BusinessEntityAddress AS BEA
INNER JOIN Person.Address AS A
ON BEA.AddressID = A.AddressID
INNER JOIN Person.EmailAddress AS EA
ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO
Veja a seguir o conjunto de resultados.
Observação
Os resultados são mostrados como cortados.
City | e-mails |
---|---|
Ballard |
paige28@adventure-works.com ;joshua24@adventure-works.com ;javier12@adventure-works.com ; ... |
Baltimore |
gilbert9@adventure-works.com |
Barstow |
kristen4@adventure-works.com |
Basingstoke Hants |
dale10@adventure-works.com ;heidi9@adventure-works.com |
Baytown |
kelvin15@adventure-works.com |
Beaverton |
billy6@adventure-works.com ;dalton35@adventure-works.com ;lawrence1@adventure-works.com ; ... |
Bell Gardens |
christy8@adventure-works.com |
Bellevue |
min0@adventure-works.com ;gigi0@adventure-works.com ;terry18@adventure-works.com ; ... |
Bellflower |
philip0@adventure-works.com ;emma34@adventure-works.com ;jorge8@adventure-works.com ; ... |
Bellingham |
christopher23@adventure-works.com ;frederick7@adventure-works.com ;omar0@adventure-works.com ; ... |
Os emails retornados na coluna de emails podem ser usados diretamente para enviar emails ao grupo de pessoas que trabalham em algumas cidades específicas.
F. Gerar uma lista classificada de emails por cidades
Semelhante ao exemplo anterior, a seguinte consulta localiza os endereços de email de funcionários, os agrupa por cidade e classifica os emails em ordem alfabética:
USE AdventureWorks2022;
GO
SELECT TOP 10 City,
STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') WITHIN GROUP (ORDER BY EmailAddress ASC) AS Emails
FROM Person.BusinessEntityAddress AS BEA
INNER JOIN Person.Address AS A
ON BEA.AddressID = A.AddressID
INNER JOIN Person.EmailAddress AS EA
ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO
Veja a seguir o conjunto de resultados.
Observação
Os resultados são mostrados como cortados.
City | Emails |
---|---|
Barstow |
kristen4@adventure-works.com |
Basingstoke Hants |
dale10@adventure-works.com ;heidi9@adventure-works.com |
Braintree |
mindy20@adventure-works.com |
Bell Gardens |
christy8@adventure-works.com |
Byron |
louis37@adventure-works.com |
Bordeaux |
ranjit0@adventure-works.com |
Carnation |
don0@adventure-works.com ;douglas0@adventure-works.com ;george0@adventure-works.com ; ... |
Boulogne-Billancourt |
allen12@adventure-works.com ;bethany15@adventure-works.com ;carl5@adventure-works.com ; ... |
Berkshire |
barbara41@adventure-works.com ;brenda4@adventure-works.com ;carrie14@adventure-works.com ; ... |
Berks |
adriana6@adventure-works.com ;alisha13@adventure-works.com ;arthur19@adventure-works.com ; ... |