Mysql
 sql >> Database >  >> RDS >> Mysql

Come restituire i risultati delle query come un elenco separato da virgole in MySQL

In MySQL, puoi restituire i risultati della query come un elenco separato da virgole utilizzando GROUP_CONCAT() funzione.

Il GROUP_CONCAT() è stata creata appositamente allo scopo di concatenare il set di risultati di una query in un elenco separato da una virgola o da un delimitatore a tua scelta.

Questo articolo fornisce esempi di come funziona.

I dati

Per prima cosa, utilizziamo i seguenti dati nei nostri primi esempi:

USE Solutions;
SELECT TaskName
FROM Tasks;

Risultato:

+-------------------+
| TaskName          |
+-------------------+
| Do garden         |
| Feed cats         |
| Paint roof        |
| Take dog for walk |
| Relax             |
| Feed cats         |
+-------------------+

Esempio di base

Ecco un esempio di base per dimostrare il GROUP_CONCAT() funzione:

SELECT GROUP_CONCAT(TaskName) 
FROM Tasks;

Risultato:

+------------------------------------------------------------------+
| GROUP_CONCAT(TaskName)                                           |
+------------------------------------------------------------------+
| Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats |
+------------------------------------------------------------------+

Come puoi vedere, ogni riga del set di risultati è stata concatenata in una singola riga. Per impostazione predefinita, l'elenco è separato da una virgola.

Nota che ci sono restrizioni sulla lunghezza di questo elenco. Maggiori informazioni su questo più avanti nell'articolo.

Esempio – DISTINTO

Puoi utilizzare DISTINCT per rimuovere i duplicati (in modo che i record duplicati diventino un record).

Esempio:

SELECT GROUP_CONCAT(DISTINCT TaskName) 
FROM Tasks;

Risultato:

+--------------------------------------------------------+
| GROUP_CONCAT(DISTINCT TaskName)                        |
+--------------------------------------------------------+
| Do garden,Feed cats,Paint roof,Relax,Take dog for walk |
+--------------------------------------------------------+

Quindi, in questo caso, "Dai da mangiare ai gatti" viene elencato solo una volta, mentre nell'esempio precedente era elencato due volte.

Esempio – ORDINA PER

Puoi utilizzare ORDER BY per ordinare i risultati in base a una determinata colonna.

Esempio:

SELECT GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) 
FROM Tasks;

Risultato:

+--------------------------------------------------------+
| GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) |
+--------------------------------------------------------+
| Take dog for walk,Relax,Paint roof,Feed cats,Do garden |
+--------------------------------------------------------+

Quindi in questo caso uso DESC per specificare che dovrebbe essere in ordine decrescente. Il valore alternativo (e predefinito) è ASC per ascendente.

Esempio:specifica un delimitatore

Per impostazione predefinita, l'elenco è un elenco separato da virgole. Tuttavia, puoi specificare un delimitatore a tua scelta, se necessario.

Per fare ciò, usa SEPARATOR seguito dal valore letterale della stringa che deve essere inserito tra i valori del gruppo.

Esempio:

SELECT GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') 
FROM Tasks;

Risultato:

+----------------------------------------------------------------+
| GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ')                |
+----------------------------------------------------------------+
| Do garden + Feed cats + Paint roof + Relax + Take dog for walk |
+----------------------------------------------------------------+

Esempio:combinazione di colonne

Puoi anche concatenare colonne e fornire il proprio separatore fornendo un valore letterale stringa.

Esempio:

SELECT GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') 
FROM Tasks;

Risultato:

+------------------------------------------------------------------------------------+
| GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ')                                 |
+------------------------------------------------------------------------------------+
| 1) Do garden 2) Feed cats 3) Paint roof 4) Take dog for walk 5) Relax 6) Feed cats |
+------------------------------------------------------------------------------------+

In questo esempio restituiamo entrambi TaskId colonna e il TaskName colonna, separata da una parentesi chiusa e da uno spazio. Usiamo anche il SEPARATOR argomento per specificare che il delimitatore da utilizzare tra ciascuna riga (concatenata) deve essere uno spazio (invece della virgola predefinita).

Risultati raggruppati

Il GROUP_CONCAT() può essere utile nelle occasioni in cui desideri fornire un elenco di risultati, raggruppati per un'altra colonna.

Ad esempio, potresti volere un elenco di artisti, con ogni artista seguito da un elenco di album che hanno pubblicato.

Per dimostrarlo, supponiamo di avere 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, quando utilizzi questo formato, se un artista ha più di un album, quell'artista viene elencato più volte, una per ogni album.

Potremmo modificare questa query in modo che ogni artista sia elencato solo una volta. Se un artista ha più di un album, tutti gli album vengono visualizzati in un unico campo all'interno di un elenco separato da virgole. Possiamo farlo grazie a GROUP_CONCAT() funzione.

Esempio:

USE Music;
SELECT ar.ArtistName,
	GROUP_CONCAT(al.AlbumName)
FROM Artists ar
INNER JOIN Albums al
ON ar.ArtistId = al.ArtistId
GROUP BY ArtistName;

Risultato:

+------------------------+----------------------------------------------------------------------------+
| ArtistName             | GROUP_CONCAT(al.AlbumName)                                                 |
+------------------------+----------------------------------------------------------------------------+
| AC/DC                  | Powerage                                                                   |
| Allan Holdsworth       | All Night Wrong,The Sixteen Men of Tain                                    |
| Buddy Rich             | Big Swing Face                                                             |
| Devin Townsend         | Epicloud,Ziltoid the Omniscient,Casualties of Cool                         |
| Iron Maiden            | Somewhere in Time,Piece of Mind,Powerslave,Killers,No Prayer for the Dying |
| Jim Reeves             | Singing Down the Lane                                                      |
| Michael Learns to Rock | Eternity,Scandinavia,Blue Night                                            |
| The Script             | No Sound Without Silence                                                   |
| Tom Jones              | Long Lost Suitcase,Praise and Blame,Along Came Jones                       |
+------------------------+----------------------------------------------------------------------------+

Attenzione alla lunghezza!

Una cosa importante di cui devi essere consapevole quando usi GROUP_CONCAT() è che il risultato viene troncato alla lunghezza massima fornita da group_concat_max_len variabile di sistema, che ha un valore predefinito di 1024 .

Il valore di questa variabile può essere impostato su un valore più alto, utilizzando la seguente sintassi:

SET [GLOBAL | SESSION] group_concat_max_len = val;

Dove val è un numero intero senza segno.

Tuttavia, si noti che la lunghezza massima effettiva del valore restituito è essa stessa vincolata dal valore di max_allowed_packet .