MariaDB ha un GROUP_CONCAT()
funzione che ci consente di restituire colonne da una query come un elenco delimitato.
Sintassi
La sintassi è questa:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val]
[LIMIT {[offset,] row_count | row_count OFFSET offset}])
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.001 sec)
Possiamo usare GROUP_CONCAT()
per restituire tutte quelle righe come un elenco delimitato.
Per raggiungere questo obiettivo, tutto ciò che dobbiamo fare è 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.003 sec)
Ordinamento
Possiamo usare il ORDER BY
clausola per ordinare l'output di questa funzione:
SELECT GROUP_CONCAT(PetName ORDER BY PetName DESC)
FROM Pets;
Risultato:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Nota che questo ordina solo l'output di GROUP_CONCAT()
funzione – è completamente indipendente da qualsiasi ordinamento applicato a SELECT
dichiarazione stessa.
Limitazione dell'output
Possiamo usare il LIMIT
clausola per limitare il numero di elementi inclusi nell'elenco:
SELECT GROUP_CONCAT(PetName LIMIT 3)
FROM Pets;
Risultato:
Fluffy,Fetch,Scratch
Qualsiasi ordine viene applicato prima del LIMIT
clausola:
SELECT GROUP_CONCAT(PetName ORDER BY PetName DESC LIMIT 3)
FROM Pets;
Risultato:
Wag,Tweet,Scratch
Nota che il LIMIT
La clausola è supportata solo da MariaDB 10.3.3.
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
La lunghezza massima restituita in byte è determinata da group_concat_max_len
variabile di sistema del server, che per impostazione predefinita è 1M (in MariaDB 10.2.4 e versioni successive) o 1K (in MariaDB 10.2.3 e versioni precedenti). Se group_concat_max_len
è 512
o inferiore, il tipo restituito è VARBINARY
o VARCHAR
; in caso contrario, il tipo restituito è BLOB
o TEXT
. La scelta tra tipi binari o non binari dipende dall'input.
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.