【问题标题】:MySQL GROUP_CONCAT with COLUMN SPLITMySQL GROUP_CONCAT 与 COLUMN SPLIT
【发布时间】:2013-12-15 07:08:11
【问题描述】:

我正在使用 TABLE,需要逻辑帮助。

查看以下 URL 以获取表结构和示例数据。

http://sqlfiddle.com/#!2/ece06/2

表架构:

CREATE TABLE test (
  ID INTEGER,
  NAME VARCHAR (50),
  VALUE INTEGER
);

插入数据:

INSERT INTO test VALUES (1, 'A', 4);
INSERT INTO test VALUES (1, 'B', 5);
INSERT INTO test VALUES (1, 'C', 8);
INSERT INTO test VALUES (2, 'D', 9);
INSERT INTO test VALUES (2, 'E', 9);
INSERT INTO test VALUES (3, 'F', 9);
INSERT INTO test VALUES (3, 'G', 9);
INSERT INTO test VALUES (3, 'H', 9);
INSERT INTO test VALUES (3, 'I', 9);

查询:

SELECT ID, GROUP_CONCAT(NAME) AS CODE
FROM test
GROUP BY ID;

输出:

ID  CODE
1   A,B,C
2   D,E
3   F,G,H,I

预期输出:

ID  CODE   CODE   CODE  CODE
1    A      B      C    NULL
2    D      E     NULL  NULL
3    F      G      H     I

如您所见,查询的输出中包含逗号。目前我们正在使用 PHP 进行字符串连接,它在显示时会拆分!!

还有其他方法可以拆分 RESULT 并在列和同一行中显示每个值吗?结果一样?

注意:每行的代码可能有所不同。

【问题讨论】:

  • 那会是什么?在结果集中不可能有不同的列数 - 整个行集只能有相同的列数。但在您的结果中有 2、3 和 4 个逗号连接的值。那么如何“转换为列”呢?
  • 检查有问题的更新以获得预期结果。
  • 幸运的是,您最多只发布了一个 ID 的 4 个值。

标签: php mysql sql logic


【解决方案1】:

如果您知道 GROUP_CONCAT 条目的数量(我的意思是在 ID = 1 的情况下合并 3 个字段,在 2 的情况下合并 2 个字段等),那么这是一种肮脏的方式。

SELECT ID, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 1), ',', -1) AS CODE1,
If(  length(GROUP_CONCAT(NAME)) - length(replace(GROUP_CONCAT(NAME), ',', ''))>1,  
       SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 2), ',', -1) ,NULL) 
           as CODE2,
   SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 3), ',', -1) AS CODE3
FROM test
GROUP BY ID;

输出:

ID  CODE1   CODE2   CODE3
1   A          B    C
2   D       (null)  E
3   F          G    H

上面的查询假设你是 GROUP_CONCAT-ing 3 个字段。如果您正在动态生成查询,您可以尝试一下。 SQLFIDDLE

编辑: 注意:每个 ROW 的 CODE 可能会有所不同。(忽略这一点)

【讨论】:

    【解决方案2】:

    在我同事的帮助下,我们终于解决了这个问题。希望有人可能需要它。如果有人让它变得更简单,这是受欢迎的。

    BEGIN
    SET @v=0;
    
    
    SET @v1=0;
    
    
    SELECT tmp.cnt INTO @v
    FROM
      (SELECT Id,
              count(ID) AS cnt,
              GROUP_CONCAT(name)
       FROM test
       GROUP BY id) tmp
    ORDER BY tmp.cnt DESC LIMIT 1;
    
    
    SET @str=' ';
    
     WHILE(@v>@v1) DO
    SET @v1=@v1+1;
    
     IF(@str='') THEN
    SET @str=CONCAT(@str,'ID, REPLACE(SUBSTRING(SUBSTRING_INDEX(GROUP_CONCAT(NAME), '','',', @v1,'),LENGTH(SUBSTRING_INDEX(GROUP_CONCAT(NAME),'','',', @v1,'-1)) + 1),'','','''') AS Code' ,@v1);
    
     ELSE
    SET @str= CONCAT(@str,',REPLACE(SUBSTRING(SUBSTRING_INDEX(GROUP_CONCAT(NAME),'','',', @v1,'),LENGTH(SUBSTRING_INDEX(GROUP_CONCAT(NAME),'','',' , @v1,' -1)) + 1),'','','''') AS Code',@v1);
    
     END IF;
    
     END WHILE;
    
    SET @str=CONCAT('SELECT ' , @str, ' FROM test GROUP BY ID');
    
     PREPARE MYSQLQUERY
    FROM @str;
    
     EXECUTE MYSQLQUERY;
    
     DEALLOCATE PREPARE MYSQLQUERY;
    
     END
    

    【讨论】:

    • 这很好。如果我们可以 JOIN 与结果表会很好,但我认为这超出了 MySQL 的能力。
    【解决方案3】:

    将其拆分为列的唯一方法意味着您提前知道要拆分的值(例如:一列用于匹配A, D, F 的代码,另一列用于B, E, G 等等)。好像不是这样的。

    防弹方法是不在 PHP 中分组和处理结果。

    另一种可能的方式(不是我推荐的方式)是将分隔符从逗号更改为其他方式。例如:

    SELECT ID, GROUP_CONCAT(NAME SEPARATOR ';') AS CODE
    FROM test
    GROUP BY ID
    

    【讨论】:

    • 根据您的预期输出,我会选择 PHP。只需遍历结果并在结果集中动态创建额外的“列”。
    【解决方案4】:
    (SELECT ID, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 1), ',', -1) AS CODE1,
    
    If(  length(GROUP_CONCAT(NAME)) - length(replace(GROUP_CONCAT(NAME), ',', ''))>1,  
    
           SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 2), ',', -1) ,NULL)as CODE2,
    
       SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 3), ',', -1) AS CODE3,
    
           If(  length(GROUP_CONCAT(NAME)) - length(replace(GROUP_CONCAT(NAME), ',', ''))>2,  
    
           SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(NAME), ',', 4), ',', -1) ,NULL)as CODE4
    
    FROM test
    GROUP BY ID)
    

    【讨论】:

      猜你喜欢
      • 2012-05-07
      • 1970-01-01
      • 2015-02-25
      • 2016-10-16
      • 2011-11-23
      • 1970-01-01
      • 2013-08-25
      • 2014-04-13
      • 2010-09-23
      相关资源
      最近更新 更多