MySQL ha un GROUP_CONCAT()
funzione che ci consente di restituire colonne da una query come un elenco delimitato.
Restituisce un risultato stringa con il non-NULL
concatenato valori da un gruppo.
Sintassi
La sintassi è questa:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Esempio
Supponiamo di eseguire la seguente query:
SELECT PetName
FROM Pets;
E otteniamo il seguente risultato:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Possiamo usare GROUP_CONCAT()
per restituire tutte quelle righe come un elenco delimitato.
Per fare ciò, dobbiamo passare il PetName
colonna come argomento per il GROUP_CONCAT()
funzione:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Risultato:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Ordinamento
Possiamo usare il ORDER BY
clausola per ordinare l'output di questa funzione:
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Risultato:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Nota che questo ordina solo l'output di GROUP_CONCAT()
funzione – è completamente indipendente da qualsiasi ordinamento applicato a SELECT
dichiarazione stessa.
Il DISTINCT
Clausola
Possiamo usare il DISTINCT
clausola per restituire valori univoci. In altre parole, se sono presenti valori duplicati, viene restituita una sola occorrenza:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Risultato:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
In questo caso, Fluffy
appare solo una volta. Quando lo eseguiamo senza DISTINCT
clausola, Fluffy
appare due volte.
Cambiare il separatore
Per impostazione predefinita, l'elenco utilizza la virgola come delimitatore. Ma possiamo cambiarlo se vogliamo:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Risultato:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Possiamo anche usare una stringa vuota per rimuovere tutti i separatori (in modo che i valori siano concatenati):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
E otteniamo il seguente risultato:
FluffyFetchScratchWagTweetFluffyBarkMeow
Risultati di query raggruppati
Possiamo includere GROUP_CONCAT()
in una query con un GROUP BY
clausola per ottenere un risultato come questo:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Risultato:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
Nel mio database, i nomi dei tipi di animali domestici effettivi sono in un'altra tabella chiamata PetTypes
. Potremmo quindi eseguire un INNER JOIN
su PetTypes
tabella per ottenere i nomi dei tipi di animali domestici effettivi:
SELECT
pt.PetType,
GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC;
Risultato:
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Limiti di lunghezza
GROUP_CONCAT()
L'output di 's viene troncato alla lunghezza massima fornita da group_concat_max_len
variabile di sistema, che ha un valore predefinito di 1024
. Il valore può essere impostato più alto, sebbene la lunghezza massima effettiva del valore restituito sia vincolata dal valore di max_allowed_packet
.
Puoi controllare il valore corrente in questo modo:
SHOW VARIABLES LIKE '%group_concat%';
La sintassi per modificare questo valore è la seguente:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Dove val
è un numero intero senza segno.