2012-11-19 7 views
72

Wenn ich eine Tabelle mit den folgenden Daten in MySQL haben:Wie GROUP_CONCAT in einem CONCAT in MySQL verwenden

id  Name  Value 
1   A   4 
1   A   5 
1   B   8 
2   C   9 

wie kann ich es in folgendem Format erhalten?

id   Column 
1   A:4,5,B:8 
2   C:9 


Ich glaube, ich habe GROUP_CONCAT zu verwenden, aber ich bin nicht sicher, wie es funktioniert.

Antwort

100
select id, group_concat(`Name` separator ',') as `ColumnName` 
from 
(
    select id, concat(`Name`, ':', 
    group_concat(`Value` separator ',')) as `Name` 
    from mytbl 
    group by id, `Name` 
) tbl 
group by id; 

Sie können es hier sehen implementiert: Sql Fiddle Demo. Genau das, was du brauchst.

Aktualisieren Aufteilen in zwei Schritten. Zuerst erhalten wir eine Tabelle mit allen Werten (durch Komma getrennt) gegen einen eindeutigen [Name, ID]. Dann erhalten Sie Tabelle erhalten wir alle Namen und Werte als Einzelwert gegen jede eindeutige ID Sehen Sie diese hier SQL Fiddle Demo erklärt (nach unten scrollen, da es zwei Ergebnismengen hat)

bearbeiten haben einen Fehler in Frage war zu lesen, ich hatte nur nach ID gruppiert. Es werden jedoch zwei group_contacts benötigt, wenn (Werte gruppiert werden sollen nach Name und ID und dann über alle nach ID). vorherige Antwort war

select 
id,group_concat(concat(`name`,':',`value`) separator ',') 
as Result from mytbl group by id 

Sie können es hier sehen implementiert: SQL Fiddle Demo

+0

Dies gibt nicht, wonach Biswa gefragt hat. – eisberg

+3

danke sami das ist, was ich für @biswa frage – Biswa

+2

Ich denke, es ist wichtig zu warnen, dass die Verwendung nur einer Art von Separator könnte nachteilig sein. Ich schlage vor, das "Name" Trennzeichen als Semikolon (;) zu machen, und das Trennzeichen kann als Komma (,) bleiben. –

15

Versuchen:

CREATE TABLE test (
    ID INTEGER, 
    NAME VARCHAR (50), 
    VALUE INTEGER 
); 

INSERT INTO test VALUES (1, 'A', 4); 
INSERT INTO test VALUES (1, 'A', 5); 
INSERT INTO test VALUES (1, 'B', 8); 
INSERT INTO test VALUES (2, 'C', 9); 

SELECT ID, GROUP_CONCAT(NAME ORDER BY NAME ASC SEPARATOR ',') 
FROM (
    SELECT ID, CONCAT(NAME, ':', GROUP_CONCAT(VALUE ORDER BY VALUE ASC SEPARATOR ',')) AS NAME 
    FROM test 
    GROUP BY ID, NAME 
) AS A 
GROUP BY ID; 

SQL Fiddle: http://sqlfiddle.com/#!2/b5abe/9/0

+2

Ja eisberg +1. Ihre Antwort ist ziemlich genau und früher. Ich habe bei meiner ersten Antwort einen Fehler gemacht – Sami

+0

@Sami Danke! – eisberg

0

IF OBJECT_ID('master..test') is not null Drop table test

CREATE TABLE test (ID INTEGER, NAME VARCHAR (50), VALUE INTEGER); 
INSERT INTO test VALUES (1, 'A', 4); 
INSERT INTO test VALUES (1, 'A', 5); 
INSERT INTO test VALUES (1, 'B', 8); 
INSERT INTO test VALUES (2, 'C', 9); 

select distinct NAME , LIST = Replace(Replace(Stuff((select ',', +Value from test where name = _a.name for xml path('')), 1,1,''),'<Value>', ''),'</Value>','') from test _a order by 1 desc 

Mein Tabellenname ist zu testen und für Verketten Ich benutze die für XML Path ('') Syntax. Die Stuff-Funktion fügt eine Zeichenfolge in eine andere Zeichenfolge ein. Es löscht eine spezifizierte Länge von Zeichen in der ersten Zeichenfolge an der Startposition und fügt dann die zweite Zeichenfolge in der ersten Zeichenfolge an der Startposition ein.

STUFF Funktionen sieht wie folgt aus: STUFF (character_expression, Start, Länge, character_expression)

character_expression ein Ausdruck von Zeichendaten. character_expression kann eine Konstante, eine Variable oder eine Spalte von Zeichen- oder Binärdaten sein.

Start Ist ein ganzzahliger Wert, der den Speicherort zum Löschen und Einfügen angibt. Wenn Start oder Länge negativ ist, wird eine Nullzeichenfolge zurückgegeben. Wenn start länger als der erste Zeichenausdruck ist, wird eine Nullzeichenfolge zurückgegeben. Start kann vom Typ bigint sein.

Länge Eine Ganzzahl, die die Anzahl der zu löschenden Zeichen angibt. Wenn die Länge länger ist als der erste Zeichenausdruck, wird bis zum letzten Zeichen im letzten Zeichenausdruck gelöscht. Länge kann vom Typ bigint sein.

5
SELECT ID, GROUP_CONCAT(CONCAT_WS(':', NAME, VALUE) SEPARATOR ',') AS Result 
FROM test GROUP BY ID 
+7

Es wäre nett, wenn Sie Ihrer Antwort eine Beschreibung hinzufügen könnten. Dies ist ein Vorschlag, um diese und zukünftige Antworten zu verbessern. Vielen Dank! –

+0

upvoted für nicht mit einem Subselect – Heinz

+0

Vielen Dank für Ihre Antwort. Das hilft mir sehr. –

0
SELECT id, GROUP_CONCAT(CONCAT_WS(':', Name, CAST(Value AS CHAR(7))) SEPARATOR ',') AS result 
    FROM test GROUP BY id 

Sie müssen CAST oder konvertieren, andernfalls Rückkehr BLOB

sein Ergebnis ist

id   Column 
1   A:4,A:5,B:8 
2   C:9 

Sie durch das Programm wie Python oder Java erneut zur Folge behandeln müssen

2

Erstens, ich sehe nicht den Grund für eine ID, die nicht eindeutig ist, aber ich denke, es ist eine ID, die verbindet sich mit einer anderen Tabelle. Zweitens gibt es keine Notwendigkeit für Unterabfragen, die den Server schlägt. Sie tun dies in einer Abfrage, wie diese

SELECT id,GROUP_CONCAT(name, ':', value SEPARATOR "|") FROM sample GROUP BY id 

Sie schnelle und korrekte Ergebnisse zu erhalten, und Sie können das Ergebnis von diesem SEPARATOR gespalten „|“. Ich benutze immer dieses Trennzeichen, weil es unmöglich ist, es innerhalb einer Schnur zu finden, deshalb ist es einzigartig. Es gibt kein Problem mit zwei A's, Sie identifizieren nur den Wert. Oder Sie können eine weitere Kolumne haben, mit dem Buchstaben, der noch besser ist. Gefällt mir:

SELECT id,GROUP_CONCAT(DISTINCT(name)), GROUP_CONCAT(value SEPARATOR "|") FROM sample GROUP BY name