Was ist das Gegenteil von GROUP_CONCAT in MySQL?

Ich scheine sehr oft gegen dieses Problem zu sein, wo ich Daten habe, die wie folgt formatiert sind:

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

aber ich möchte es so formatiert:

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

Gibt es einen guten Weg, dies zu tun? Wie heißt diese Art von Operation?

Ich denke, es ist was Sie brauchen (gespeicherte Prozedur): Mysql Spaltenstrang in Zeilen aufgeteilt

 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; $$ 

Sie könnten eine Abfrage wie folgt verwenden:

 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 

Bitte sieh hier Geige an . Bitte beachten Sie, dass diese Abfrage bis zu 4 colors für jede Zeile unterstützt. Sie sollten Ihre Unterabfrage aktualisieren, um mehr als 4 Zahlen zurückzugeben (oder Sie sollten eine Tabelle verwenden, die 10 oder 100 Zahlen enthält).

Das hat mir viele Stunden erspart! Noch einen Schritt weiter: Bei einer typischen Implementierung würde es höchstwahrscheinlich eine Tabelle geben, die die colors gegen einen Identitätsschlüssel, color_list , color_list . Eine neue Farbe kann zu der Implementierung hinzugefügt werden, ohne die Abfrage ändern zu müssen, und die möglicherweise endlose union Klausel kann vollständig vermieden werden, indem die Abfrage folgendermaßen geändert wird:

 SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(colors, ',', n.digit+1), ',', -1) color FROM colors INNER JOIN (select id as digit from color_list) n ON LENGTH(REPLACE(colors, ',' , '')) < = LENGTH(colors)-n.digit ORDER BY id, n.digit; 

Es ist wichtig, dass die IDs in der Tabelle color_list sequenziell bleiben.

Beachten Sie, dass dies ohne Erstellen einer temporären Tabelle erfolgen kann

 select id, substring_index(substring_index(genre, ',', n), ',', -1) as genre from my_table join (SELECT @row := @row + 1 as n FROM (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t, (SELECT @row:=0) r) as numbers on char_length(genre) - char_length(replace(genre, ',', '')) >= n - 1