web-dev-qa-db-fra.com

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

En utilisant MySQL, je peux faire quelque chose comme:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Ma sortie:

shopping
fishing
coding

mais au lieu de cela, je veux juste 1 ligne, 1 colonne:

Résultat attendu:

shopping, fishing, coding

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

J'ai cherché une fonction sur MySQL Doc et cela ne ressemble pas aux fonctions CONCAT ou CONCAT_WS qui acceptent les ensembles de résultats, personne ici ne sait comment faire cela. ?

1109
Dean Rather

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 l'opérateur 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 l'imploser à l'aide de _ORDER BY_:

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

Comme Dag a déclaré dans son commentaire , le résultat est limité à 1024 octets. 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_ selon 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
);
_
1605
che

Regardez 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';
96
lpfavreau

Autre syntaxe pour concaténer plusieurs lignes individuelles

AVERTISSEMENT: Ce message vous donnera faim.

Donné:

Je me suis retrouvé à vouloir sélectionner plusieurs lignes individuelles - au lieu d'un groupe - et les concaténer sur un certain champ.

Supposons que vous disposiez d'un tableau des identifiants de produits, de leurs noms et de leurs prix:

+------------+--------------------+-------+
| product_id | name               | price |
+------------+--------------------+-------+
|         13 | Double Double      |     5 |
|         14 | Neapolitan Shake   |     2 |
|         15 | Animal Style Fries |     3 |
|         16 | Root Beer          |     2 |
|         17 | Lame T-Shirt       |    15 |
+------------+--------------------+-------+

Ensuite, vous avez un ajax fantaisie-schmancy qui liste ces chiots comme des cases à cocher.

Votre utilisateur faim-hippo sélectionne 13, 15, 16. Pas de dessert pour elle aujourd'hui ...

Trouver:

Une façon de résumer la commande de votre utilisateur en une seule ligne, avec pur mysql.

Solution:

Utilisez GROUP_CONCAT avec le la clause IN :

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);

Quelles sorties:

+------------------------------------------------+
| order_summary                                  |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+

Solution bonus:

Si vous voulez aussi le prix total, ajoutez SUM() :

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16);
+------------------------------------------------+-------+
| order_summary                                  | total |
+------------------------------------------------+-------+
| Double Double + Animal Style Fries + Root Beer |    10 |
+------------------------------------------------+-------+

PS: Toutes mes excuses si vous n'avez pas de In-N-Out à proximité ...

66

Vous pouvez modifier la longueur maximale de la valeur GROUP_CONCAT en définissant le paramètre group_concat_max_len.

Voir les détails dans MySQL documantation .

37
pau.moreno

Il existe une fonction GROUP Aggregate, GROUP_CONCAT .

26
Dean Rather

Dans mon cas, j'avais une rangée d'identifiants qu'il était nécessaire de convertir en caractères, sinon le résultat était codé au format binaire:

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

Utilisez la variable de session MySQL (5.6.13) et l’opérateur d’affectation comme suit

SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;

alors vous pouvez obtenir

test1,test11
14
Shen liang

J'avais une requête plus compliquée et j'ai trouvé que je devais utiliser GROUP_CONCAT dans une requête externe pour que cela fonctionne:

Requête originale:

SELECT DISTINCT userID 
FROM event GROUP BY userID 
HAVING count(distinct(cohort))=2);

Implosé:

SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') 
FROM (SELECT DISTINCT userID FROM event 
GROUP BY userID HAVING count(distinct(cohort))=2) as sub;

J'espère que cela pourrait aider quelqu'un.

12
Alex Bowyer

Essaye ça:

DECLARE @Hobbies NVARCHAR(200) = ' '

SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;
7
thejustv

Pour ceux qui cherchent ici, comment utiliser GROUP_CONCAT avec une sous-requête - publier cet exemple

SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid

Donc, GROUP_CONCAT doit être utilisé à l'intérieur de la sous-requête, sans l'envelopper.

4
Oleg Abrazhaev

nous avons deux façons de concaténer des colonnes dans MySql

select concat(hobbies) as `Hobbies` from people_hobbies where 1

Ou

select group_concat(hobbies) as `Hobbies` from people_hobbies where 1
0
raghavendra