A partire da SQL Server 2017, ora puoi visualizzare i risultati della query come un elenco. Ciò significa che puoi visualizzare il tuo set di risultati come un elenco separato da virgole, un elenco separato da spazi o qualsiasi separatore tu scelga di utilizzare.
Sebbene fosse vero che potevi ottenere lo stesso effetto prima di SQL Server 2017, era un po' complicato.
Transact-SQL ora ha il STRING_AGG()
funzione, che concatena i valori delle espressioni stringa e inserisce valori separatori tra di loro. Funziona più o meno allo stesso modo di GROUP_CONCAT()
di MySQL funzione.
Questo articolo fornisce esempi che dimostrano il STRING_AGG()
T-SQL funzione.
Dati di esempio
Innanzitutto, ecco alcuni dati di esempio.
SELECT TaskId, TaskName FROM Tasks;
Risultato:
TaskId TaskName ------ ------------ 1 Feed cats 2 Water dog 3 Feed garden 4 Paint carpet 5 Clean roof 6 Feed cats
Esempio:elenco separato da virgole
Quindi potremmo prendere i dati sopra e usare STRING_AGG()
funzione per elencare tutti i nomi delle attività in un grande elenco separato da virgole.
In questo modo:
SELECT STRING_AGG(TaskName, ', ') FROM Tasks;
Risultato:
Feed cats, Water dog, Feed garden, Paint carpet, Clean roof, Feed cats
Naturalmente, non deve necessariamente essere separato da una virgola. Può essere separato da qualsiasi espressione di NVARCHAR
o VARCHAR
digitare e può essere un valore letterale o una variabile.
Esempio:combinazione di colonne
Potremmo anche usare CONCAT()
funzione per combinare due campi insieme, separati dal proprio separatore.
Esempio:
SELECT STRING_AGG(CONCAT(TaskId, ') ', TaskName), ' ') FROM Tasks;
Risultato:
1) Feed cats 2) Water dog 3) Feed garden 4) Paint carpet 5) Clean roof 6) Feed cats
Esempio:valori nulli
Se il set di risultati contiene valori nulli, tali valori vengono ignorati e non viene aggiunto un separatore corrispondente.
Se questo non è adatto, puoi fornire un valore per i valori null utilizzando ISNULL()
funzione e passando il valore che desideri utilizzare ogni volta che viene rilevato un valore nullo. In questo modo si assicura di ottenere comunque un risultato quando una riga contiene un valore null.
Ad esempio, considera la query e il set di risultati seguenti:
SELECT TaskCode FROM Tasks;
Risultato:
TaskCode -------- cat123 null null pnt456 rof789 null
Possiamo vedere che ci sono tre valori nulli all'interno del set di risultati.
Se lo eseguiamo attraverso il STRING_AGG()
funzione, otteniamo questo:
SELECT STRING_AGG(TaskCode, ', ') FROM Tasks;
Risultato:
cat123, pnt456, rof789
Tuttavia, se utilizziamo ISNULL()
funzione per fornire un segnaposto per qualsiasi valore nullo, otteniamo questo:
SELECT STRING_AGG(ISNULL(TaskCode, 'N/A'), ', ') FROM Tasks;
Risultato:
cat123, N/A, N/A, pnt456, rof789, N/A
Esempio:risultati raggruppati
Puoi anche usare STRING_AGG()
funzione quando si raggruppa il set di risultati. Ad esempio, potresti volere un elenco di album raggruppati per artista.
Per dimostrarlo, immagina un database con due tabelle; Artists
e Albums
. C'è una relazione uno a molti tra queste tabelle. Per ogni artista potrebbero esserci molti album.
Quindi una query normale che unisce entrambe le tabelle potrebbe assomigliare a questa:
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Risultato:
ArtistName AlbumName ------------------------- ------------------------ Iron Maiden Powerslave AC/DC Powerage Jim Reeves Singing Down the Lane Devin Townsend Ziltoid the Omniscient Devin Townsend Casualties of Cool Devin Townsend Epicloud Iron Maiden Somewhere in Time Iron Maiden Piece of Mind Iron Maiden Killers Iron Maiden No Prayer for the Dying The Script No Sound Without Silence Buddy Rich Big Swing Face Michael Learns to Rock Blue Night Michael Learns to Rock Eternity Michael Learns to Rock Scandinavia Tom Jones Long Lost Suitcase Tom Jones Praise and Blame Tom Jones Along Came Jones Allan Holdsworth All Night Wrong Allan Holdsworth The Sixteen Men of Tain
Come puoi vedere, se un artista ha più di un album, il nome dell'artista viene elencato più volte, una per ogni album.
Ma possiamo usare STRING_AGG()
per modificare questa impostazione in modo da elencare ogni artista una sola volta, seguito da un elenco separato da virgole degli album che hanno pubblicato:
USE Music; SELECT ar.ArtistName, STRING_AGG(al.AlbumName, ', ') FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Risultato:
ArtistName ------------------------- ------------------------------------------------------------------------------ AC/DC Powerage Allan Holdsworth All Night Wrong, The Sixteen Men of Tain Buddy Rich Big Swing Face Devin Townsend Ziltoid the Omniscient, Casualties of Cool, Epicloud Iron Maiden Powerslave, Somewhere in Time, Piece of Mind, Killers, No Prayer for the Dying Jim Reeves Singing Down the Lane Michael Learns to Rock Blue Night, Eternity, Scandinavia The Script No Sound Without Silence Tom Jones Long Lost Suitcase, Praise and Blame, Along Came Jones
Esempio:ordinamento dei risultati
È possibile utilizzare una clausola order per ordinare i risultati all'interno del gruppo concatenato. Questo viene fatto con il WITHIN GROUP
clausola. Quando si utilizza questa clausola, si specifica l'ordine con ORDER BY
seguito da ASC
(per ascendente) o DESC
(per discendente).
Esempio:
USE Music; SELECT ar.ArtistName, STRING_AGG(al.AlbumName, ', ') WITHIN GROUP (ORDER BY al.AlbumName DESC) FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Risultato:
ArtistName ------------------------- ------------------------------------------------------------------------------ AC/DC Powerage Allan Holdsworth The Sixteen Men of Tain, All Night Wrong Buddy Rich Big Swing Face Devin Townsend Ziltoid the Omniscient, Epicloud, Casualties of Cool Iron Maiden Somewhere in Time, Powerslave, Piece of Mind, No Prayer for the Dying, Killers Jim Reeves Singing Down the Lane Michael Learns to Rock Scandinavia, Eternity, Blue Night The Script No Sound Without Silence Tom Jones Praise and Blame, Long Lost Suitcase, Along Came Jones