Puis-je concaténer plusieurs lignes MySQL en 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 Rangée, 1 col:
Résultats Escomptés:
shopping, fishing, coding
la raison est que je sélectionne des valeurs multiples à partir de plusieurs tables, et après tout les jointures, j'ai beaucoup plus de lignes que je voudrais.
J'ai cherché une fonction sur MySQL Doc et elle ne ressemble pas aux fonctions CONCAT
ou CONCAT_WS
acceptent les ensembles de résultats, donc quelqu'un ici sait comment faire cela?
9 réponses
vous pouvez utiliser GROUP_CONCAT
:
SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies GROUP BY person_id
comme Ludwig 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 a déclaré dans leur commentaire, vous pouvez également trier les valeurs avant de l'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 a déclaré dans son commentaire, il y a une limite de 1024 octets sur le résultat. Pour résoudre ceci, lancez 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
)
regardez GROUP_CONCAT
si votre version MySQL (4.1) le supporte. Voir la documentation pour plus de détails.
ça ressemblerait à quelque chose comme:
SELECT GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
WHERE person_id = 5
GROUP BY 'all';
syntaxe alternative à concaténate multiple, lignes individuelles
AVERTISSEMENT: Ce post va vous donner faim.
:
je me suis trouvé à vouloir sélectionner plusieurs, lignes individuelles - au lieu d'un groupe-et concaténer sur un certain champ.
disons que vous avez une table d'ID de produit et leurs noms et 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 |
+------------+--------------------+-------+
alors vous avez un ajax de fantaisie-schmancy qui liste ces chiots au loin comme des cases à cocher.
votre utilisateur de hungry-hippo sélectionne 13, 15, 16
. Pas de dessert pour elle aujourd'hui...
Rechercher:
une façon de résumer l'ordre de votre Utilisateur en une seule ligne, avec pur mysql.
Solution:
utiliser GROUP_CONCAT
avec le le IN
clause :
mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);
qui produit:
+------------------------------------------------+
| order_summary |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+
Solution Bonus:
si vous voulez le prix total aussi, Lancez 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: excuses si vous n'avez pas un In-N-Out à proximité...
vous pouvez modifier la longueur maximale de la valeur GROUP_CONCAT
en paramétrant le paramètre group_concat_max_len
.
voir les détails dans le MySQL documantation .
dans mon cas, j'ai eu une rangée d'ID, et il était nécessaire de la lancer sur char, sinon, le résultat a été encodé en format binaire:
SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
utiliser MySQL (5.6.13) variable de session et opérateur d'affectation comme le suivant
SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;
alors vous pouvez obtenir
test1,test11
j'ai eu une requête plus compliquée, et j'ai trouvé que j'ai dû utiliser GROUP_CONCAT
dans une requête externe pour le faire fonctionner:
Requête Originale:
SELECT DISTINCT userID
FROM event GROUP BY userID
HAVING count(distinct(cohort))=2);
a 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 ça pourrait aider quelqu'un.
essayez ceci:
DECLARE @Hobbies NVARCHAR(200) = ' '
SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;