Dans MySQL, vous pouvez renvoyer les résultats de votre requête sous forme de liste séparée par des virgules en utilisant le GROUP_CONCAT()
fonction.
Le GROUP_CONCAT()
a été créée spécifiquement dans le but de concaténer le jeu de résultats d'une requête dans une liste séparée par une virgule ou un délimiteur de votre choix.
Cet article fournit des exemples de la façon dont tout cela fonctionne.
Les données
Commençons par utiliser les données suivantes dans nos premiers exemples :
USE Solutions; SELECT TaskName FROM Tasks;
Résultat :
+-------------------+ | TaskName | +-------------------+ | Do garden | | Feed cats | | Paint roof | | Take dog for walk | | Relax | | Feed cats | +-------------------+
Exemple de base
Voici un exemple de base pour démontrer le GROUP_CONCAT()
fonction :
SELECT GROUP_CONCAT(TaskName) FROM Tasks;
Résultat :
+------------------------------------------------------------------+ | GROUP_CONCAT(TaskName) | +------------------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats | +------------------------------------------------------------------+
Comme vous pouvez le voir, chaque ligne du jeu de résultats a été concaténée en une seule ligne. Par défaut, la liste est séparée par une virgule.
Notez qu'il existe des restrictions sur la longueur de cette liste. Plus d'informations à ce sujet plus loin dans l'article.
Exemple - DISTINCT
Vous pouvez utiliser DISTINCT
pour supprimer les doublons (afin que les enregistrements en double deviennent un seul enregistrement).
Exemple :
SELECT GROUP_CONCAT(DISTINCT TaskName) FROM Tasks;
Résultat :
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName) | +--------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Relax,Take dog for walk | +--------------------------------------------------------+
Ainsi, dans ce cas, "Feed cats" n'est répertorié qu'une seule fois, alors qu'il était répertorié deux fois dans l'exemple précédent.
Exemple – COMMANDER PAR
Vous pouvez utiliser ORDER BY
pour trier les résultats par une colonne donnée.
Exemple :
SELECT GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) FROM Tasks;
Résultat :
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) | +--------------------------------------------------------+ | Take dog for walk,Relax,Paint roof,Feed cats,Do garden | +--------------------------------------------------------+
Donc dans ce cas j'utilise DESC
pour spécifier qu'il doit être dans l'ordre décroissant. La valeur alternative (et par défaut) est ASC
pour monter.
Exemple – Spécifier un délimiteur
Par défaut, la liste est une liste séparée par des virgules. Cependant, vous pouvez spécifier un délimiteur de votre choix si nécessaire.
Pour ce faire, utilisez SEPARATOR
suivi de la valeur littérale de chaîne qui doit être insérée entre les valeurs de groupe.
Exemple :
SELECT GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') FROM Tasks;
Résultat :
+----------------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') | +----------------------------------------------------------------+ | Do garden + Feed cats + Paint roof + Relax + Take dog for walk | +----------------------------------------------------------------+
Exemple – Combinaison de colonnes
Vous pouvez également concaténer des colonnes et fournir leur propre séparateur en fournissant une valeur littérale de chaîne.
Exemple :
SELECT GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') FROM Tasks;
Résultat :
+------------------------------------------------------------------------------------+ | GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') | +------------------------------------------------------------------------------------+ | 1) Do garden 2) Feed cats 3) Paint roof 4) Take dog for walk 5) Relax 6) Feed cats | +------------------------------------------------------------------------------------+
Dans cet exemple, nous renvoyons à la fois le TaskId
colonne et le TaskName
colonne, séparés par une parenthèse fermante et un espace. Nous utilisons également le SEPARATOR
argument pour spécifier que le délimiteur à utiliser entre chaque ligne (concaténée) doit être un espace (au lieu de la virgule par défaut).
Résultats groupés
Le GROUP_CONCAT()
La fonction peut être utile lorsque vous souhaitez fournir une liste de résultats, regroupés par une autre colonne.
Par exemple, vous pourriez vouloir une liste d'artistes, avec chaque artiste suivi d'une liste d'albums qu'ils ont sortis.
Pour illustrer cela, disons que nous avons une base de données avec deux tables; Artists
et Albums
. Il existe une relation un à plusieurs entre ces tables. Pour chaque artiste, il peut y avoir plusieurs albums.
Ainsi, une requête régulière joignant les deux tables pourrait ressembler à ceci :
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Résultat :
+------------------------+--------------------------+ | 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 | +------------------------+--------------------------+
Comme vous pouvez le voir, lorsque vous utilisez ce format, si un artiste a plus d'un album, cet artiste est répertorié plusieurs fois - une fois pour chaque album.
Nous pourrions modifier cette requête afin que chaque artiste ne soit répertorié qu'une seule fois. Si un artiste a plus d'un album, tous les albums sont affichés dans un seul champ dans une liste séparée par des virgules. Nous pouvons le faire grâce au GROUP_CONCAT()
fonction.
Exemple :
USE Music; SELECT ar.ArtistName, GROUP_CONCAT(al.AlbumName) FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Résultat :
+------------------------+----------------------------------------------------------------------------+ | 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 | +------------------------+----------------------------------------------------------------------------+
Attention à la longueur !
Une chose importante dont vous devez être conscient lorsque vous utilisez GROUP_CONCAT()
est que le résultat est tronqué à la longueur maximale fournie par le group_concat_max_len
variable système, qui a une valeur par défaut de 1024
.
La valeur de cette variable peut être définie plus haut, en utilisant la syntaxe suivante :
SET [GLOBAL | SESSION] group_concat_max_len = val;
Où val
est un entier non signé.
Cependant, notez que la longueur maximale effective de la valeur de retour est elle-même contrainte par la valeur de max_allowed_packet
.