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 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.
D. Restituire articoli di giornale con tag correlati
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 ; ... |