Compartilhar via


STRING_AGG (Transact-SQL)

Applies to: SQL Server 2017 (14.x) and later Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsSQL analytics endpoint in Microsoft FabricWarehouse in 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

Syntax

STRING_AGG ( expression , separator ) [ <order_clause> ]

<order_clause> ::=
    WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )

Arguments

expression

An expression of any type. Expressions are converted to nvarchar or varchar types during concatenation. Non-string types are converted to nvarchar type.

separator

An expression of nvarchar or varchar type that is used as separator for concatenated strings. 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>

    A list of non-constant expressions that can be used for sorting results. Apenas uma <order_by_expression_list> é permitida por consulta. A ordem de classificação padrão é crescente.

Return types

O tipo de retorno depende do primeiro argumento (expressão). If input argument is string type (nvarchar, varchar), the result type is the same as the input type. A seguinte tabela lista as conversões automáticas:

Tipo de expressão de entrada Result
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
int, bigint, smallint, tinyint, numeric, float, real, bit,
decimal, smallmoney, money, datetime, datetime2
nvarchar(4000)

Remarks

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.

If the input expression is type varchar, the separator can't be type nvarchar.

Valores nulos são ignorados e o separador correspondente não é adicionado. To return a place holder for null values, use the ISNULL function as demonstrated in example B.

STRING_AGG está disponível em qualquer nível de compatibilidade.

Note

O <order_clause> está disponível com o nível de compatibilidade do banco de dados 110 e superior.

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2022 ou AdventureWorksDW2022, que você pode baixar na página inicial 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.

Note

Se você usar 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 intermediários separados por vírgula sem valores NULL

O exemplo a seguir substitui NULL os valores N/A e retorna os nomes separados por vírgulas em uma única célula de resultado.

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), ISNULL(MiddleName, 'N/A')), ',') AS csv
FROM Person.Person;
GO

Aqui está um conjunto de resultados cortado.

csv
-----
E,R.,N/A,N/A,B,E,N/A,N/A,N/A,N/A,G,B,N/A,C,J,L,P,N/A,M,N/A,N/A,N/A,L,J., ...

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)
...

Note

Se você usar 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.

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 title tags
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

Note

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

Aqui está o conjunto de resultados cortados.

City emails
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

Aqui está o conjunto de resultados 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; ...