Verwendung von GROUP_CONCAT in einem CONCAT in MySQL

115

Wenn ich eine Tabelle mit den folgenden Daten in MySQL habe:

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

Wie bekomme ich es in das folgende Format?

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


Ich denke ich muss verwenden GROUP_CONCAT. Aber ich bin mir nicht sicher, wie es funktioniert.

Biswa
quelle

Antworten:

158
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 implementiert sehen: SQL Fiddle Demo . Genau das, was Sie brauchen.

Aktualisieren Sie die Aufteilung in zwei Schritten. Zuerst erhalten wir eine Tabelle mit allen Werten (durch Kommas getrennt) gegen ein eindeutiges [Name, ID]. Dann erhalten wir aus der erhaltenen Tabelle alle Namen und Werte als einen einzigen Wert für jede eindeutige ID. Siehe dies hier erklärt SQL Fiddle Demo (scrollen Sie nach unten, da es zwei Ergebnismengen hat)

Bearbeiten Es gab einen Fehler beim Lesen der Frage, ich hatte nur nach ID gruppiert. Es werden jedoch zwei group_contacts benötigt, wenn (Werte sollen verkettet werden, gruppiert nach Name und ID und dann insgesamt 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 implementiert sehen: SQL Fiddle Demo

Sami
quelle
Dies gibt nicht das, wonach Biswa gefragt hat.
Eisberg
3
Ich denke, es ist wichtig, die Menschen zu warnen, dass die Verwendung nur einer Art von Trennzeichen nachteilig sein kann. Ich schlage vor, das "Name" -Trennzeichen als Semikolon (;) zu setzen, und das Wertetrennzeichen kann als Komma (,) bleiben
Fandi Susanto
4
Bitte beachten Sie auch, dass GROUP_CONCATdie Ausgabe möglicherweise stillschweigend abgeschnitten wird group_concat_max_len. SET group_concat_max_len=...wird helfen, aber es ist trotzdem eine gute Idee zu überprüfen, ob die zurückgegebene (Byte?) Länge kleiner als ist group_concat_max_len.
Tuomassalo
2
Beachten Sie auch, dass group_concat auf einen einzelnen NULL-Wert stößt und die gesamte Zeile, in der er enthalten ist, weglässt. Ich arbeite , um dieses in dem zweiten Vorbehalt hier .
MatrixManAtYrService
1
Wenn jemand Probleme mit dem in der Antwort angegebenen SQL Fiddle-Link hat. Working Fiddle ist hier: sqlfiddle.com/#!9/42f994/601/0
Hitesh
21

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

Eisberg
quelle
2
Ja Eisberg +1. Ihre Antwort ist ziemlich genau und früher. Ich habe einen Fehler in meiner ersten Antwort gemacht
Sami
8
SELECT ID, GROUP_CONCAT(CONCAT_WS(':', NAME, VALUE) SEPARATOR ',') AS Result 
FROM test GROUP BY ID
John
quelle
7
Es wäre schön, wenn Sie Ihrer Antwort eine Beschreibung hinzufügen könnten. Dies ist ein Vorschlag, um diese und zukünftige Antworten zu verbessern. Vielen Dank!
Luís Cruz
5

Zunächst sehe ich keinen Grund für eine ID, die nicht eindeutig ist, aber ich denke, es ist eine ID, die eine Verbindung zu einer anderen Tabelle herstellt. Zweitens sind keine Unterabfragen erforderlich, was den Server verprügelt. Sie tun dies in einer Abfrage, wie folgt

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

Sie erhalten schnelle und korrekte Ergebnisse und können das Ergebnis durch diesen SEPARATOR "|" teilen. Ich benutze dieses Trennzeichen immer, weil es unmöglich ist, es in einer Zeichenfolge zu finden, daher ist es einzigartig. Es ist kein Problem, zwei A zu haben. Sie identifizieren nur den Wert. Oder Sie können noch eine Spalte mit dem Buchstaben haben, was noch besser ist. So was :

SELECT id,GROUP_CONCAT(DISTINCT(name)), GROUP_CONCAT(value SEPARATOR "|") FROM sample GROUP BY name
Lucian Minea
quelle
2
 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 convert verwenden, andernfalls wird BLOB zurückgegeben

Ergebnis ist

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

Sie müssen das Ergebnis noch einmal mit einem Programm wie Python oder Java verarbeiten

lglcomcn
quelle
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 test und zur Konkatination verwende ich die Syntax For XML Path (''). Die Stuff-Funktion fügt eine Zeichenfolge in eine andere Zeichenfolge ein. Es löscht eine bestimmte Länge von Zeichen in der ersten Zeichenfolge an der Startposition und fügt dann die zweite Zeichenfolge in die erste Zeichenfolge an der Startposition ein.

STUFF-Funktionen sehen folgendermaßen aus: STUFF (Zeichenausdruck, Start, Länge, Zeichenausdruck)

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

start Ist ein ganzzahliger Wert, der den Speicherort für das 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 Ist eine Ganzzahl, die die Anzahl der zu löschenden Zeichen angibt. Wenn die Länge länger als der erste Zeichenausdruck ist, erfolgt das Löschen bis zum letzten Zeichen im letzten Zeichenausdruck. Länge kann vom Typ Bigint sein.

Novy
quelle
0

SELECT-ID, Group_concat ( column) FROM (SELECT-ID, Concat ( name, ':', Group_concat ( value)) AS column FROM mytbl GROUP BY-ID, Name) tbl GROUP BY-ID;

Mrigank Shekhar
quelle