2013-11-29 118 views
2

我正在使用TABLE,需要合理的帮助。MySQL GROUP_CONCAT与COLUMN SPLIT

检查表格结构和样本数据的以下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 

正如你可以看到查询的输出已经Concat的用逗号。而目前我们正在使用PHP在显示时分割字符串concat!

是否有任何其他方式来分割RESULT并显示列和相同的行中的每个值?同样的结果呢?

注意:对于每个行,CODE可能会有所不同。

+0

那么会是什么?在结果集中不可能有不同数量的列 - 对于整个行集,只能有相同的列数。但在你的结果中有2,3和4个逗号加入的值。那么如何才能“转换为列”呢? –

+0

检查有问题的更新以获取预期结果。 – TomPHP

+0

幸运的是,您只发布了最多一个ID的4个值。 –

回答

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 @[email protected]+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 
+1

这非常好。如果我们可以加入到结果表中,这将是非常好的,但我认为这超出了MySQL的功能。 – pbarney

0

将其拆分为列的唯一方法将意味着您知道要提前拆分的值(例如:匹配A, D, F的另一个代码的一列,以及B, E, G等的一列)。这似乎并非如此。

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

另一种可能的方式(不是我推荐的方法)就是将saparator从逗号改成其他的。 EG:

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

检查有问题的更新以获得预期结果。 @Mosty – TomPHP

+1

根据您的预期输出,我会去PHP。只需迭代结果并在结果集中动态创建额外的“列”即可。 –

1

如果知道GROUP_CONCAT条目(我的意思是3个字段中= 1个2字段被组合在2等的情况下ID的情况下的组合)的数量,再有一个肮脏的方式。

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

编辑: 注意:该代码可能会有所不同,每个行。 (忽略此项)