带有COLUMN SPLIT的MySQL GROUP_CONCAT

时间:2013-11-29 06:38:06

标签: php mysql sql logic

我正在使用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并显示列中的每个值和相同的ROW?在同样的结果?

注意:每个ROW的CODE可能会有所不同。

4 个答案:

答案 0 :(得分:2)

如果你知道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-3个字段。如果您动态生成查询,可以尝试一下。 SQLFIDDLE

修改 注意:每个ROW的CODE可能会有所不同。(忽略此项)

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

将其拆分为列的唯一方法是让您知道要预先拆分的值(例如:代码匹配A, D, F的代码为一列B, E, G另有代码,依此类推)。情况似乎并非如此。

防弹方法不是按PHP分组并处理结果。

另一种可能的方式(不是我推荐的方式)是将saparator从逗号更改为其他内容。 EG:

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

答案 3 :(得分:-1)

(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)