MySQL a un GROUP_CONCAT()
fonction qui nous permet de renvoyer les colonnes d'une requête sous forme de liste délimitée.
Il renvoie un résultat de chaîne avec le non-NULL
concaténé valeurs d'un groupe.
Syntaxe
La syntaxe ressemble à ceci :
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Exemple
Supposons que nous lancions la requête suivante :
SELECT PetName
FROM Pets;
Et nous obtenons le résultat suivant :
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Nous pouvons utiliser GROUP_CONCAT()
pour renvoyer toutes ces lignes sous forme de liste délimitée.
Pour ce faire, nous devons passer le PetName
colonne comme argument du GROUP_CONCAT()
fonction :
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Résultat :
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Commander
Nous pouvons utiliser le ORDER BY
clause pour ordonner la sortie de cette fonction :
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Résultat :
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Notez que cela ne trie que la sortie du GROUP_CONCAT()
fonction - elle est complètement indépendante de tout ordre appliqué au SELECT
déclaration elle-même.
Le DISTINCT
Article
Nous pouvons utiliser le DISTINCT
clause pour retourner des valeurs uniques. En d'autres termes, s'il y a des valeurs en double, une seule occurrence est renvoyée :
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Résultat :
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
Dans ce cas, Fluffy
n'apparaît qu'une seule fois. Lorsque nous l'exécutons sans le DISTINCT
clause, Fluffy
apparaît deux fois.
Changer le séparateur
Par défaut, la liste utilise la virgule comme délimiteur. Mais nous pouvons changer cela si nous le souhaitons :
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Résultat :
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Nous pouvons même utiliser une chaîne vide pour supprimer tous les séparateurs (afin que les valeurs soient concaténées) :
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
Et nous obtenons le résultat suivant :
FluffyFetchScratchWagTweetFluffyBarkMeow
Résultats de requête groupés
Nous pouvons inclure GROUP_CONCAT()
dans une requête avec un GROUP BY
clause pour obtenir un résultat comme celui-ci :
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Résultat :
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
Dans ma base de données, les noms réels des types d'animaux se trouvent dans une autre table appelée PetTypes
. Nous pourrions donc exécuter un INNER JOIN
sur les PetTypes
table pour obtenir les noms réels des types d'animaux :
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;
Résultat :
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Limites de longueur
GROUP_CONCAT()
La sortie de est tronquée à la longueur maximale donnée par le group_concat_max_len
variable système, qui a une valeur par défaut de 1024
. La valeur peut être supérieure, bien que la longueur maximale effective de la valeur de retour soit limitée par la valeur de max_allowed_packet
.
Vous pouvez vérifier la valeur actuelle comme ceci :
SHOW VARIABLES LIKE '%group_concat%';
La syntaxe pour changer cette valeur est la suivante :
SET [GLOBAL | SESSION] group_concat_max_len = val;
Où val
est un entier non signé.