2012-11-19 258 views
72

如果我有一個表在MySQL以下數據:如何使用GROUP_CONCAT在CONCAT在MySQL

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

我怎麼讓它進入下面的格式?

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


我想我必須使用GROUP_CONCAT,但我不知道它是如何工作的。

回答

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; 

你可以看到它實現這裏:Sql Fiddle Demo。確切地說你需要什麼。

更新 分兩步拆分。首先,我們得到一個表格,其中包含所有值(逗號分隔)與唯一的[名稱,ID]。然後,從獲得的表格中我們得到的所有名稱和值作爲對每一個唯一的ID 單個值見這說明如下SQL Fiddle Demo(向下滾動,因爲它有兩個結果集)

編輯有閱讀問題上的錯誤,我僅通過id分組。但是,如果需要兩個group_contacts(值按照Name和id分組,然後通過id分組)。 以前的答案是

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

你可以看到它實現這裏:SQL Fiddle Demo

+0

這不會給Biswa要求什麼。 – eisberg

+3

謝謝薩米這就是我要求的@biswa – Biswa

+2

我認爲它很重要,警告人們只使用一種分離器可能是不利的。我建議將「名稱」分隔符設置爲分號(;),值分隔符可以保留爲逗號(,) –

15

嘗試:

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小提琴:http://sqlfiddle.com/#!2/b5abe/9/0

+2

是eisberg +1。你的回答非常準確和早。我在第一次回答時出錯了 – Sami

+0

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

我的表名是測試,併爲concatination我用的是對於XML路徑( '' ) 句法。 stuff函數將字符串插入另一個字符串中。它刪除起始位置第一個字符串中指定長度的字符 ,然後將第二個字符串插入到起始位置的第一個字符串 。

STUFF功能看起來像這樣:STUFF(一個character_expression,啓動,長度,一個character_expression)

一個character_expression 是字符數據的表達式。 character_expression可以是字符或二進制數據的常量,變量或列。

開始 是一個整數值,指定開始刪除和插入的位置。如果開始或長度爲負值,則返回空字符串 。如果start比第一個character_expression長,則返回空字符串。 start可以是bigint類型。

長度 是一個整數,指定要刪除的字符數。如果長度比第一個字符表達式長,則會發生 直到最後一個字符表達式中的最後一個字符。長度可以是bigint類型。

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

如果你可以給你的答案添加一些描述,那將是很好的。這是一個改進這個和未來答案的建議。謝謝! –

+0

upvoted for not using a subselect – Heinz

+0

謝謝你的回答。這對我有很大的幫助。 –

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

,你必須使用CAST或轉換,否則將返回BLOB

結果是

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

您必須通過程序如Python或Java

處理再次引起
2

首先,我沒有看到具有不唯一ID的原因,但我想這是一個ID連接到另一個表。 其次,不需要子查詢,這會打敗服務器。你在一個查詢做到這一點,像這樣

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

你得到快速和正確的結果,並且可以通過分隔符分開的結果「|」。我總是使用這個分隔符,因爲它不可能在一個字符串中找到它,因此它是唯一的。 有兩個A沒有問題,你只能確定這個值。或者你可以再加一個柱子,這封信甚至更好。 喜歡傾向:

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