2012-11-19 14 views
72

Jeśli mam tabelę z następujących danych w MySQL:Jak korzystać GROUP_CONCAT w CONCAT w MySQL

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

jak mogę to w następującym formacie?

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


Chyba muszę używać GROUP_CONCAT, ale nie jestem pewien, jak to działa.

Odpowiedz

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; 

Widać to realizowane tutaj: Sql Fiddle Demo. Dokładnie to, czego potrzebujesz.

Aktualizacja Dzielenie w dwóch etapach. Najpierw otrzymujemy tabelę zawierającą wszystkie wartości (oddzielone przecinkami) od unikalnego [Nazwa, identyfikator]. Następnie z otrzymanego tabeli otrzymujemy wszystkie nazwy i wartości jako pojedynczej wartości wobec każdego unikalnego identyfikatora Zobacz to wyjaśnione tutaj SQL Fiddle Demo (przewinąć w dół, jak to ma dwa zestawy wynik)

Edycja Nastąpiła pomyłka w czytaniu pytanie, zgrupowane tylko według identyfikatora. Ale dwa group_contacts są potrzebne, jeśli (Wartości mają być łączone pogrupowane według nazwy i id, a następnie przez wszystkie id). Poprzednia odpowiedź była

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

Widać to realizowane tutaj: SQL Fiddle Demo

+0

To nie daje tego, o co prosi Biswa. – eisberg

+3

dziękuję, sami, o to proszę o @biswa – Biswa

+2

Uważam, że ważne jest ostrzeganie ludzi, że używanie tylko jednego rodzaju separatora może być niekorzystne. Proponuję uczynić separator "name" jako średnik (;), a separator wartości może pozostać jako przecinek (,) –

15

Spróbuj:

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

Tak eisberg +1. Twoja odpowiedź jest dość dokładna i wcześniejsza. Popełniłem błąd w mojej pierwszej odpowiedzi – Sami

+0

@Sami Dziękuję! – 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 

Nazywam tabela testy, a dla concatination używam Dla XML Path ('') składnia. Funkcja stuff wstawia ciąg do innego ciągu. Usuwa określoną długość znaków w pierwszym ciągu w pozycji początkowej, a następnie wstawia drugi ciąg do pierwszego ciągu w pozycji początkowej.

funkcje rzeczy wygląda następująco: STUFF (character_expression, start, długość, character_expression)

character_expression jest wyrazem danych znakowych. character_expression może być stałą, zmienną lub kolumną o wartości lub danych binarnych.

Uruchom Jest to wartość całkowita, która określa lokalizację, od której należy rozpocząć usuwanie i wstawianie. Jeśli start lub length jest ujemny, zwracany jest pusty łańcuch znaków. Jeśli start jest dłuższy niż pierwszy character_expression, zwracany jest łańcuch pusty. start może być typu bigint.

długość Jest liczbą całkowitą określającą liczbę znaków do usunięcia. Jeśli długość jest dłuższa niż pierwsze wyrażenie_znakowe, usunięcie do ostatniego znaku z ostatniego wyrażenia_znakowego następuje po . długość może być typu bigint.

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

Byłoby miło, gdybyś mógł dodać jakiś opis do swojej odpowiedzi. Jest to sugestia, aby poprawić tę i przyszłe odpowiedzi. Dzięki! –

+0

przegłosowano, aby nie używać podselekcji – Heinz

+0

dziękuję za odpowiedź. to mi bardzo pomaga. –

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

należy użyć obsady lub konwersji, w przeciwnym razie będzie powrót BLOB

wynik jest

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

trzeba obsłużyć doprowadzić ponownie przez program takich jak Python lub Java

2

Po pierwsze, nie widzę powodu, dla którego identyfikator nie jest unikalny, ale domyślam się, że to identyfikator łączy się z inną tabelą. Po drugie nie ma potrzeby podkwerend, które biją serwer. Można to zrobić w jednym zapytaniu, jak to

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

Ci uzyskać szybkie i poprawne wyniki, można podzielić wynik przez ten separator „|”. Zawsze używam tego separatora, ponieważ nie można go znaleźć w ciągu znaków, dlatego jest wyjątkowy. Nie ma problemu z dwoma A, identyfikujesz tylko wartość. Lub możesz mieć jeszcze jedną kolumnę, z literą, która jest jeszcze lepsza. Na przykład:

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