2012-11-19 5 views
72

Se ho una tabella con i seguenti dati in MySQL:Come utilizzare group_concat in un CONCAT in MySQL

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

come faccio a farlo nel seguente formato?

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


penso che devo usare GROUP_CONCAT, ma non sono sicuro di come funziona.

risposta

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; 

Potete vederlo implementato qui: Sql Fiddle Demo. Esattamente quello di cui hai bisogno.

Aggiornamento Divisione in due passaggi. Per prima cosa otteniamo una tabella con tutti i valori (separati da virgola) rispetto a un [Name, id] univoco. Poi da tavola ottenuti otteniamo tutti i nomi ei valori come un singolo valore contro l'ID univoco Vedi questo spiegato qui SQL Fiddle Demo (scorrere verso il basso in quanto ha due set di risultati)

Modifica C'è stato un errore nella lettura di domanda, aveva raggruppato solo da id. Ma se sono necessari due group_contacts (i valori devono essere concatenati raggruppati per nome e id e quindi per intero per id). risposta precedente era

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

Potete vederlo implementato qui: SQL Fiddle Demo

+0

Questo non dà ciò che Biswa ha chiesto. – eisberg

+3

grazie sami, questo è quello che sto chiedendo @biswa – Biswa

+2

Penso che sia importante avvertire i popoli che l'uso di un solo tipo di separatore potrebbe essere svantaggioso. Suggerisco di fare il separatore "nome" come punto e virgola (;), e il separatore dei valori può rimanere come virgola (,) –

15

Prova:

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

Sì eisberg +1. La tua risposta è praticamente esatta e precedente. Ho fatto un errore nella mia prima risposta al tempo – Sami

+0

@Sami Grazie! – 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 

Il mio nome della tabella è di test, e per concatination uso il Per XML Path ('' sintassi. La funzione stuff inserisce una stringa in un'altra stringa. Elimina una lunghezza specificata di caratteri nella prima stringa nella posizione iniziale e quindi inserisce la seconda stringa nella prima stringa nella posizione iniziale.

funzioni roba sembra come questo: STUFF (character_expression, inizio, lunghezza, character_expression)

character_expression è espressione di dati di caratteri. character_expression può essere una costante, una variabile o una colonna di carattere o di dati binari.

start È un valore intero che specifica la posizione in cui iniziare l'eliminazione e l'inserimento. Se start o length è negativo, viene restituita una stringa nulla. Se start è più lungo del primo character_expression, viene restituita una stringa nulla. start può essere di tipo bigint.

lunghezza È un numero intero che specifica il numero di caratteri da eliminare. Se la lunghezza è più lunga della prima character_expression, l'eliminazione di si verifica fino all'ultimo carattere nell'ultimo carattere_espressione. la lunghezza può essere di tipo bigint.

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

Sarebbe bello se potessi aggiungere qualche descrizione alla tua risposta. Questo è un suggerimento per migliorare questa e le future risposte. Grazie! –

+0

upvoted per non utilizzare una sottoselezione – Heinz

+0

grazie per la risposta. questo mi aiuta molto –

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

è necessario utilizzare getto o convertire, in caso contrario sarà BLOB ritorno

risultato è

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

si deve comportare gestire ancora una volta da programma come Python o Java

2

Prima di tutto, non vedo la ragione per avere un ID che non è univoco, ma immagino che sia un ID che si connette a un altro tavolo. Secondo non c'è bisogno di sottoquery, che batte il server. A tale scopo, in una query, come questo

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

È possibile ottenere risultati veloci e corretti, e si può dividere il risultato per quel separatore "|". Uso sempre questo separatore, perché è impossibile trovarlo all'interno di una stringa, quindi è unico. Non ci sono problemi con due A, si identifica solo il valore. Oppure puoi avere un'altra colonna, con la lettera, che è ancora meglio. In questo modo:

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