【问题标题】:How to use GROUP_CONCAT in a CONCAT in MySQL如何在 MySQL 的 CONCAT 中使用 GROUP_CONCAT
【发布时间】:2012-11-07 05:53:13
【问题描述】:

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

【问题讨论】:

    标签: mysql concat group-concat


    【解决方案1】:
    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

    【讨论】:

    • 这并没有满足 Biswa 的要求。
    • 我认为警告人们只使用一种分隔符可能是不利的,这一点很重要。我建议将“名称”分隔符设置为分号(;),值分隔符可以保留为逗号(,)
    • 还请注意GROUP_CONCAT 可能会默默地将其输出截断为group_concat_max_lenSET group_concat_max_len=... 会有所帮助,但无论如何检查返回的(字节?)长度是否小于 group_concat_max_len 是个好主意。
    • 还要注意 group_concat 遇到单个 NULL 值,它将忽略包含它的整个行。我在第二个警告here 中解决了这个问题。
    • 如果有人遇到答案中给出的 SQL Fiddle 链接问题。工作小提琴在这里:sqlfiddle.com/#!9/42f994/601/0
    【解决方案2】:

    试试:

    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

    【讨论】:

      【解决方案3】:
      SELECT ID, GROUP_CONCAT(CONCAT_WS(':', NAME, VALUE) SEPARATOR ',') AS Result 
      FROM test GROUP BY ID
      

      【讨论】:

      • 如果您可以在答案中添加一些描述,那就太好了。这是一个改进这个和未来答案的建议。谢谢!
      【解决方案4】:

      首先,我看不出 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
      

      【讨论】:

        【解决方案5】:
         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等程序再次处理结果

        【讨论】:

          【解决方案6】:
          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; 
          

          【讨论】:

            【解决方案7】:

            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 可以是常量、变量或列 字符或二进制数据。

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

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

            【讨论】:

              猜你喜欢
              • 2017-10-15
              • 2011-11-23
              • 2012-10-28
              • 2015-03-30
              • 2011-06-24
              • 1970-01-01
              • 2018-09-04
              • 1970-01-01
              相关资源
              最近更新 更多