Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the opposite of GROUP_CONCAT in MySQL?

I seem to come against this problem a lot, where I have data that's formatted like this:

+----+----------------------+ | id | colors               | +----+----------------------+ | 1  | Red,Green,Blue       | | 2  | Orangered,Periwinkle | +----+----------------------+ 

but I want it formatted like this:

+----+------------+ | id | colors     | +----+------------+ | 1  | Red        | | 1  | Green      | | 1  | Blue       | | 2  | Orangered  | | 2  | Periwinkle | +----+------------+ 

Is there a good way to do this? What is this kind of operation even called?

like image 336
Jason Hamje Avatar asked Jun 25 '13 22:06

Jason Hamje


People also ask

What does Group_concat do in MySQL?

GROUP_CONCAT is a function which concatenates/merges the data from multiple rows into one field. It is a GROUP BY function which returns a string if the group contains at least 1 non-null value, if it does not, it returns a Null value.

Is there a length limit to Group_concat?

Show activity on this post. I'm using GROUP_CONCAT() in a MySQL query to convert multiple rows into a single string. However, the maximum length of the result of this function is 1024 characters.


2 Answers

You could use a query like this:

SELECT   id,   SUBSTRING_INDEX(SUBSTRING_INDEX(colors, ',', n.digit+1), ',', -1) color FROM   colors   INNER JOIN   (SELECT 0 digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) n   ON LENGTH(REPLACE(colors, ',' , '')) <= LENGTH(colors)-n.digit ORDER BY   id,   n.digit 

Please see fiddle here. Please notice that this query will support up to 4 colors for every row, you should update your subquery to return more than 4 numbers (or you should use a table that contains 10 or 100 numbers).

like image 87
fthiella Avatar answered Oct 10 '22 02:10

fthiella


I think it is what you need (stored procedure) : Mysql split column string into rows

DELIMITER $$  DROP PROCEDURE IF EXISTS explode_table $$ CREATE PROCEDURE explode_table(bound VARCHAR(255))  BEGIN  DECLARE id INT DEFAULT 0; DECLARE value TEXT; DECLARE occurance INT DEFAULT 0; DECLARE i INT DEFAULT 0; DECLARE splitted_value INT; DECLARE done INT DEFAULT 0; DECLARE cur1 CURSOR FOR SELECT table1.id, table1.value                                      FROM table1                                      WHERE table1.value != ''; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;  DROP TEMPORARY TABLE IF EXISTS table2; CREATE TEMPORARY TABLE table2( `id` INT NOT NULL, `value` VARCHAR(255) NOT NULL ) ENGINE=Memory;  OPEN cur1;   read_loop: LOOP     FETCH cur1 INTO id, value;     IF done THEN       LEAVE read_loop;     END IF;      SET occurance = (SELECT LENGTH(value)                              - LENGTH(REPLACE(value, bound, ''))                              +1);     SET i=1;     WHILE i <= occurance DO       SET splitted_value =       (SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(value, bound, i),       LENGTH(SUBSTRING_INDEX(value, bound, i - 1)) + 1), ',', ''));        INSERT INTO table2 VALUES (id, splitted_value);       SET i = i + 1;      END WHILE;   END LOOP;    SELECT * FROM table2;  CLOSE cur1;  END; $$ 
like image 22
kmas Avatar answered Oct 10 '22 03:10

kmas