Base SQL : concaténer plusieurs lignes (rows) en une chaîne (string) unique
Les systèmes de gestion de bases de données intègrent des fonctions supplémentaires qui rendent possible le fait de regrouper plusieurs lignes.
Concaténer plusieurs lignes en une seule chaîne n'est pas possible avec le langage SQL. Mais les systèmes de gestion de bases de données ont apporté des fonctions supplémentaires qui rendent possible le fait de regrouper plusieurs lignes en une seule chaîne de caractères. Pour illustrer l'exemple, utilisons la table suivante :
ma_table prenom Jean Paul Pierre
Depuis la version 2005, SQL Server fournit dans le langage Transact-SQL la méthode XML PATH qui permet d'associer plusieurs lignes d'une même colonne. En ajoutant la clause FOR XML PATH et en précisant une valeur vide en argument, il est possible de concaténer les valeurs contenues dans les lignes. Les valeurs seront systématiquement concaténées avec un espace. Pour ajouter un séparateur entre les valeurs, il faut l'indiquer dans le SELECT.
SELECT prenom + ',' AS [text()] FROM ma_table FOR XML PATH('') Résultat : Jean, Paul, Pierre,
Avec cette requête, il y a une virgule supplémentaire dans les valeurs sélectionnées. Pour gérer ce cas, on peut utiliser la fonction LEFT, qui retourne le nombre de caractères d'une chaîne en partant de la gauche, combinée à la fonction LEN qui calcule la longueur d'une chaîne.
SELECT LEFT(prenoms, LEN(prenoms) - 1) FROM ( SELECT prenom + ',' AS prenoms AS [text()] FROM ma_table FOR XML PATH('') ) Résultat : Jean, Paul, Pierre
Dans le langage Transact SQL, il est possible de déclarer une variable puis de la remplir avec un SELECT. La solution ne fonctionne pas s'il y a une valeur NULL dans la table, il faut donc penser à exclure la valeur NULL dans la condition.
DECLARE @Prenoms VARCHAR(8000) SELECT @Prenoms = COALESCE(@Prenoms + ', ', '') + prenom FROM ma_table WHERE nom IS NOT NULL Résultat : Jean, Paul, Pierre
Si vous utilisez le système de gestion de base de données MySQL, la fonction GROUP_CONCAT permet de regrouper des lignes entre elles avec la clause GROUP BY. Si vous n'avez pas de colonne permettant de regrouper les valeurs, utilisez la valeur 1 dans une colonne qui n'existe pas avec un alias.
SELECT 1 AS a, GROUP_CONCAT(prenom ORDER BY prenom ASC SEPARATOR ', ') AS prenoms FROM ma_table GROUP BY a
Pour Postgre SQL, la fonction utilisée dépend de la version installée. Pour une base de données gérée par Postgre SQL en version 9 ou plus récente, il faut utiliser la fonction string_agg(). Pour une version antérieure, on fait appel à la fonction array_agg() qui crée un tableau avec les données, puis on utilise la fonction array_to_string() pour convertir le tableau en chaîne de caractères.
SELECT string_agg(prenom, ',') FROM prenoms; SELECT array_to_string(array_agg(prenom), ', ') AS prenoms FROM ma_table; Résultat : Jean, Paul, Pierre