STRING_AGG (Transact-SQL)

Si applica a: SQL Server 2017 (14.x) e versioni successive database SQL di Azure Istanza gestita di SQL di Azure endpoint 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 tipi NVARCHAR o VARCHAR durante la concatenazione. I tipi non stringa vengono convertiti nel tipo NVARCHAR.

separator
È un'espressione di tipo NVARCHAR o VARCHAR usata come separatore per 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 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 sarà uguale al tipo dell'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, numeric, float, real, bit, decimal, 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 (Transact-SQL).

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 nell'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

La maggior parte degli esempi di questo articolo fa riferimento ai database di esempio AdventureWorks.

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 Risultati in formato griglia 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 l'elenco di nomi delimitati da virgola senza valori NULL

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

Il set di risultati è il seguente.

Nota

I risultati vengono visualizzati tagliati.

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

Il set di risultati è il seguente.

Nota

I risultati vengono visualizzati tagliati.

nomi
Ken Sánchez (8 febbraio 2003 12:00)
Terri Duffy (24 febbraio 2002 12:00)
Roberto Tamburello (5 dicembre 2001 12:00)
Rob Walters (29 dicembre 2001 12:00)
...

Nota

Se si usa l'editor di query di Management Studio, l'opzione Risultati in formato 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 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 I sondaggi indicano risultati delle elezioni molto vicini politica, sondaggi, municipio
176 La nuova autostrada dovrebbe ridurre il traffico NULL
177 I cani continuano a essere preferiti ai gatti sondaggi, animali

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

Passaggi successivi

Per altre informazioni sulle funzioni Transact-SQL, vedere gli articoli seguenti: