STRING_AGG (Transact-SQL)

Si applica a: SQL Server 2017 (14.x) e versioni successive database SQL di Azure Istanza gestita di SQL di Azureendpoint di analisi SQL di Azure Synapse Analytics in Microsoft Fabric Warehouse in Microsoft Fabric

Concatena i valori delle espressioni della stringa e inserisce i valori dei separatori tra di essi. Il separatore non viene aggiunto alla fine della stringa.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

STRING_AGG ( expression , separator ) [ <order_clause> ]

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

Argomenti

expression

Espressione di qualsiasi tipo. Le espressioni vengono convertite in nvarchar o tipi varchar durante la concatenazione. I tipi non stringa vengono convertiti in tipo di nvarchar.

separator

Espressione di nvarchar o tipo varchar utilizzato come separatore per le stringhe concatenate. Può essere un valore letterale o una variabile.

<order_clause>

Facoltativamente è possibile specificare l'ordine dei risultati concatenati mediante la clausola WITHIN GROUP:

WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
  • <order_by_expression_list>

    Elenco di espressioni non costanti che può essere usato per l'ordinamento dei risultati. È consentito un solo valore <order_by_expression_list> per query. Per impostazione predefinita, l'ordinamento è crescente.

Tipi restituiti

Il tipo restituito dipende dal primo argomento (expression). Se l'argomento di input è di tipo stringa (nvarchar, varchar), il tipo di risultato corrisponde al tipo di input. Nella tabella seguente sono elencate le conversioni automatiche:

Tipo di espressione di input Risultato
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
int, bigint, smallint, tinyint, numerico, float, real, bit,
decimale, smallmoney, money, datetime, datetime2
nvarchar(4000)

Osservazioni:

STRING_AGG è una funzione di aggregazione che accetta tutte le espressioni dalle righe e le concatena in una stringa singola. I valori delle espressioni vengono convertiti in modo implicito nei tipi di stringa e successivamente concatenati. Per la conversione implicita in stringhe vengono seguite le regole esistenti per le conversioni dei tipi di dati. Per altre informazioni sulle conversioni dei tipi di dati, vedere CAST e CONVERT.

Se l'espressione di input è di tipo varchar, il separatore non può essere di tipo nvarchar.

I valori Null vengono ignorati e il separatore corrispondente non viene aggiunto. Per restituire un segnaposto per i valori Null, usare la funzione ISNULL come illustrato in esempio B.

STRING_AGG è disponibile in qualsiasi livello di compatibilità.

Nota

<order_clause> è disponibile con il livello di compatibilità del database 110 e livelli superiori.

Esempi

Gli esempi di codice Transact-SQL in questo articolo usano il database di esempio AdventureWorks2022 o AdventureWorksDW2022, che è possibile scaricare dalla home page Microsoft SQL Server Samples and Community Projects.

R. Generare l'elenco di nomi separati in nuove righe

Nell'esempio seguente viene generato un elenco di nomi in una cella di risultato singola, separati con ritorno a capo.

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), FirstName), CHAR(13)) AS csv
FROM Person.Person;
GO

Il set di risultati è il seguente.

csv
-----------
Syed
Catherine
Kim
Kim
Kim
Hazem
...

I valori NULL presenti nelle celle name non vengono restituiti nel risultato.

Nota

Se si usa l'editor di query di SQL Server Management Studio, l'opzione Results to Grid non può implementare il ritorno a capo. Passare a Risultati in formato testo per visualizzare il risultato impostato correttamente. Per impostazione predefinita, i risultati in formato testo vengono troncati a 256 caratteri. Per aumentare questo limite, modificare l'opzione Numero massimo di caratteri visualizzati in ogni colonna.

B. Generare un elenco di nomi separati da virgole senza NULL valori

Nell'esempio seguente i valori Null vengono sostituiti con "N/A" e i nomi delimitati da virgole vengono restituiti in una cella di risultato singola.

USE AdventureWorks2022;
GO

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

Ecco un set di risultati tagliato.

csv
-----
Syed,Catherine,Kim,Kim,Kim,Hazem,Sam,Humberto,Gustavo,Pilar,Pilar, ...

C. Generare valori delimitati da virgole

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), CONCAT(FirstName, ' ', LastName, '(', ModifiedDate, ')')), CHAR(13)) AS names
FROM Person.Person;
GO

Ecco un set di risultati tagliato.

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

Nota

Se si usa l'editor di query di Management Studio, l'opzione risultati in griglia non può implementare il ritorno a capo. Passare a Risultati in formato testo per visualizzare il risultato impostato correttamente.

Si supponga di avere un database in cui gli articoli e i relativi tag siano separati in tabelle diverse. Uno sviluppatore vuole che venga restituita una riga per ogni articolo con tutti i tag associati. La query seguente ottiene questo risultato:

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

Il set di risultati è il seguente.

articleId title tag
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

Nota

La clausola GROUP BY è obbligatoria se la funzione STRING_AGG non è l'unico elemento nell'elenco SELECT.

E. Generare un elenco di messaggi di posta elettronica per città

La query seguente consente di trovare gli indirizzi di posta elettronica dei dipendenti e di raggrupparli in base alla città:

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

Il set di risultati è il seguente.

Nota

I risultati vengono visualizzati tagliati.

Città messaggi e-mail
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; ...

I messaggi di posta elettronica restituiti nella colonna relativa possono essere usati per inviare messaggi di posta elettronica a un gruppo di persone che lavorano tutte nella stessa città.

F. Generare un elenco di messaggi di posta elettronica ordinato per città

La query seguente è simile alla precedente e consente di trovare gli indirizzi di posta elettronica dei dipendenti, di raggrupparli in base alla città e di metterli in ordine alfabetico:

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

Il set di risultati è il seguente.

Nota

I risultati vengono visualizzati tagliati.

Città Messaggi e-mail
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; ...