129

如果我在 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. 但我不确定它是如何工作的。

4

7 回答 7

174
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。正是你需要的。

分两步更新拆分。首先,我们得到一个表,其中所有值(逗号分隔)都针对唯一的 [Name,id]。然后从获得的表中,我们将所有名称和值作为每个唯一 id 的单个值查看这里解释的SQL Fiddle Demo(向下滚动,因为它有两个结果集)

编辑阅读问题时出错,我只按id分组。但是如果(值将按名称和 id 分组,然后按 id 分组)则需要两个 group_contacts。以前的答案是

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

你可以在这里看到它的实现:SQL Fiddle Demo

于 2012-11-19T10:33:11.880 回答
23

尝试:

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

于 2012-11-19T10:20:56.030 回答
9
SELECT ID, GROUP_CONCAT(CONCAT_WS(':', NAME, VALUE) SEPARATOR ',') AS Result 
FROM test GROUP BY ID
于 2014-12-22T13:20:36.257 回答
6

首先,我看不出 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
于 2017-08-14T16:55:15.307 回答
4
 SELECT id, GROUP_CONCAT(CONCAT_WS(':', Name, CAST(Value AS CHAR(7))) SEPARATOR ',') AS result 
    FROM test GROUP BY id

您必须使用 cast 或 convert,否则将返回 BLOB

结果是

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

您必须通过 python 或 java 等程序再次处理结果

于 2017-05-17T07:04:55.493 回答
1
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; 
于 2019-10-06T18:05:32.427 回答
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

我的表名是 test ,对于连接,我使用 For XML Path('') 语法。stuff 函数将一个字符串插入到另一个字符串中。它在开始位置删除第一个字符串中指定长度的字符,然后将第二个字符串插入到开始位置的第一个字符串中。

STUFF 函数如下所示: STUFF (character_expression , start , length ,character_expression )

character_expression 是字符数据的表达式。character_expression 可以是常量、变量或字符或二进制数据的列。

start 是一个整数值,指定开始删除和插入的位置。如果 start 或 length 为负数,则返回空字符串。如果 start 比第一个 character_expression 长,则返回一个空字符串。start 可以是 bigint 类型。

length 是一个整数,指定要删除的字符数。如果长度比第一个 character_expression 长,则删除直到最后一个 character_expression 中的最后一个字符。长度可以是 bigint 类型。

于 2013-11-28T09:35:30.763 回答