web-dev-qa-db-de.com

Kann ich mehrere MySQL-Zeilen in einem Feld zusammenfassen?

Mit MySQL kann ich Folgendes tun:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

Meine Ausgabe:

shopping
fishing
coding

stattdessen möchte ich nur 1 Zeile, 1 Spalte:

Erwartete Ausgabe:

shopping, fishing, coding

Der Grund ist, dass ich mehrere Werte aus mehreren Tabellen auswähle und nach all den Verknüpfungen viel mehr Zeilen habe, als ich möchte.

Ich habe nach einer Funktion für MySQL Doc gesucht und es sieht nicht so aus, als ob die Funktionen CONCAT oder CONCAT_WS Ergebnismengen akzeptieren ?

1109
Dean Rather

Sie können GROUP_CONCAT verwenden:

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

Wie Ludwig in sein Kommentar angegeben hat, können Sie den Operator DISTINCT hinzufügen, um Duplikate zu vermeiden:

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

Wie Jan in ihr Kommentar angegeben hat, können Sie die Werte auch sortieren, bevor Sie sie mit _ORDER BY_ implodieren:

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

Wie Dag in sein Kommentar feststellte, ist das Ergebnis auf 1024 Byte begrenzt. Um dies zu lösen, führen Sie diese Abfrage vor Ihrer Abfrage aus:

_SET group_concat_max_len = 2048;
_

Natürlich können Sie _2048_ nach Ihren Wünschen ändern. So berechnen Sie den Wert und weisen ihn zu:

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

Schauen Sie sich GROUP_CONCAT an, wenn Ihre MySQL-Version (4.1) dies unterstützt. Siehe die Dokumentation für weitere Details.

Es würde ungefähr so ​​aussehen:

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

Alternative Syntax zum Verketten mehrerer einzelner Zeilen

WARNUNG: Dieser Beitrag macht hungrig.

Gegeben:

Ich wollte mehrere einzelne Zeilen - anstelle einer Gruppe - auswählen und in einem bestimmten Feld verketten.

Angenommen, Sie haben eine Tabelle mit Produkt-IDs sowie deren Namen und Preisen:

+------------+--------------------+-------+
| 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 |
+------------+--------------------+-------+

Dann haben Sie einen ausgefallenen Ajax, in dem diese Welpen als Kontrollkästchen aufgeführt sind.

Ihr Hunger-Nilpferd-Benutzer wählt 13, 15, 16. Kein Dessert für sie heute ...

Finden:

Eine Möglichkeit, die Bestellung Ihres Benutzers in einer Zeile mit reinem MySQL zusammenzufassen.

Lösung:

Verwenden Sie GROUP_CONCAT mit der der IN -Klausel :

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

Welche Ausgänge:

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

Bonus Lösung:

Wenn Sie auch den Gesamtpreis sehen möchten, werfen Sie 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: Entschuldigung, wenn Sie kein In-N-Out in der Nähe haben ...

66

Sie können die maximale Länge des Werts GROUP_CONCAT ändern, indem Sie den Parameter group_concat_max_len einstellen.

Details finden Sie in der MySQL-Dokumentation .

37
pau.moreno

Es gibt eine GROUP Aggregate-Funktion GROUP_CONCAT .

26
Dean Rather

In meinem Fall hatte ich eine Reihe von IDs, und es war notwendig, diese in char umzuwandeln. Andernfalls wurde das Ergebnis im Binärformat codiert:

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

Verwenden Sie die Sitzungsvariable MySQL (5.6.13) und den Zuweisungsoperator wie folgt

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

dann kannst du bekommen

test1,test11
14
Shen liang

Ich hatte eine kompliziertere Abfrage und stellte fest, dass ich GROUP_CONCAT in einer äußeren Abfrage verwenden musste, um sie zum Laufen zu bringen:

Ursprüngliche Abfrage:

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

Implodiert:

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

Hoffe das könnte jemandem helfen.

12
Alex Bowyer

Versuche dies:

DECLARE @Hobbies NVARCHAR(200) = ' '

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

Für jemanden, der hier nachschaut, wie man GROUP_CONCAT mit Unterabfrage verwendet - dieses Beispiel posten

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

Also muss GROUP_CONCAT in der Unterabfrage verwendet werden, nicht umbrochen.

4
Oleg Abrazhaev

wir haben zwei Möglichkeiten, um Spalten in MySQL zu verketten

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

Oder

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