Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come restituire i risultati delle query come elenco separato da virgole in SQL Server – STRING_AGG()

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