1478 votes

Puis-je concaténer plusieurs lignes MySQL dans un seul champ ?

Utilisation de MySQL je peux faire quelque chose comme :

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Ma sortie :

shopping
fishing
coding

mais à la place, je veux juste 1 ligne, 1 colonne :

Résultats attendus :

shopping, fishing, coding

La raison en est que je sélectionne plusieurs valeurs dans plusieurs tables et qu'après toutes les jointures, j'ai beaucoup plus de lignes que je ne le voudrais.

J'ai cherché une fonction sur Doc MySQL et il ne semble pas que le CONCAT o CONCAT_WS Les fonctions acceptent les ensembles de résultats.

Est-ce que quelqu'un ici sait comment faire ?

10 votes

Je viens d'écrire une petite démo sur l'utilisation de group_concat qui pourrait vous être utile : giombetti.com/2013/06/06/mysql-group_concat

0 votes

0 votes

Vous pouvez utiliser xpath pour faire pivoter les lignes dans les colonnes

2085voto

che Points 6899

Vous pouvez utiliser GROUP_CONCAT :

SELECT person_id,
   GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Comme Ludwig l'a déclaré dans son commentaire, vous pouvez ajouter le DISTINCT pour éviter les doublons :

SELECT person_id,
   GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Comme Jan l'a déclaré dans leur commentaire, vous pouvez également trier les valeurs avant de les imploser en utilisant ORDER BY :

SELECT person_id, 
       GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Comme Dag l'a déclaré dans son commentaire, il y a une limite de 1024 octets sur le résultat. Pour résoudre ce problème, exécutez cette requête avant votre requête :

SET group_concat_max_len = 2048;

Bien sûr, vous pouvez changer 2048 en fonction de vos besoins. Pour calculer et attribuer la valeur :

SET group_concat_max_len = CAST(
                     (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
                           FROM peoples_hobbies
                           GROUP BY person_id) AS UNSIGNED);

175 votes

Soyez juste conscient de la limitation à 1024 octets de la colonne résultante (voir le paramètre groupe_concat_max_len )

87 votes

Et en ajoutant le DISTINCT vous n'obtiendrez aucun double. ... GROUP_CONCAT(DISTINCT hobbies)

126voto

lpfavreau Points 5622

Jetez un coup d'œil à GROUP_CONCAT si votre version de MySQL (4.1) le supporte. Voir la documentation pour plus de détails.

Cela ressemblerait à quelque chose comme :

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';

15 votes

Je pense que group by 'all' n'est pas nécessaire (et d'ailleurs indésirable), car elle affecte à toutes les lignes la chaîne de caractères all et ensuite comparer les chaînes de caractères entre ces rangées. Ai-je raison ?

41voto

pau.moreno Points 1061

Vous pouvez modifier la longueur maximale de la GROUP_CONCAT en réglant la valeur group_concat_max_len paramètre.

Voir les détails dans le Documentation sur MySQL .

31voto

Dean Rather Points 7856

Il existe une fonction GROUP Aggregate, GROUPE_CONCAT .

28voto

Fedir Points 3235

Dans mon cas, j'avais une ligne d'Ids, et il était nécessaire de la convertir en char, sinon, le résultat était encodé en format binaire :

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X