2016-04-15 7 views
1

ich tabelle1 habe:Mysql Split Zeile einzufügen

id - values 
12 - 124,145,135 
16 - 254,33,11,456,78 

...

Mit SQL, wie kann ich die Werte aufgeteilt in eine andere Tabelle einfügen zu erhalten:

INSERT INTO table2 (id,cat) VALUES 12, 124; 
INSERT INTO table2 (id,cat) VALUES 12, 145; 
INSERT INTO table2 (id,cat) VALUES 12, 135; 
INSERT INTO table2 (id,cat) VALUES 16, 254; 
... 

Vielen Dank!

+2

Zu kompliziert und kann nicht mit nur SQL erfolgen, müssen Sie zumindest einige gespeicherte Prozedur beinhalten, das zu tun. Besser tun Sie es über ein serverseitiges Skript (wie PHP), wo die Lösung mehr als einfach ist. – mitkosoft

Antwort

0

Hilft Ihnen das? Split strings using mysql

Falls die Anzahl der verketteten Werte in der Spalte „Werte“ ist unbekannt oder variierende ich für die answer gehen würde, die eine separate Funktion verwendet (SPLIT_STR). Sonst wird es sehr kompliziert.

0

Hier ist, wie Sie es in MySQL tun könnte:

INSERT INTO table2 
SELECT id, 
     REPLACE(substring(substring_index(vals, ',', i), 
       length(substring_index(vals, ',', i - 1)) + 1), ',', '') 
FROM (
    SELECT a.*, @i := if(@id = a.id, @i + 1, 1) i, @id := a.id 
    FROM (
     SELECT * 
     FROM table1 a 
     INNER JOIN information_schema.global_status b ON 1 = 1 
     ORDER BY a.id 
    ) a 
    INNER JOIN (SELECT @i := 0, @id := NULL) x 
) a 
WHERE i <= LENGTH(vals) - LENGTH(REPLACE(vals, ',', '')) + 1 

Offensichtlich ist die wichtigste Frage, die zweite Spalte auf Zeilen zu konvertieren war.

Hier ist, wie es funktioniert (man sollte es von den inneren Abfragen zu lesen beginnen):

INSERT INTO table2 
SELECT id, 
     /* Get i-th CSV value from vals (where i ranges between 1 
      and number of generated rows) */ 
     REPLACE(substring(substring_index(vals, ',', i), 
       length(substring_index(vals, ',', i - 1)) + 1), ',', '') 
FROM (
    SELECT a.*, 

      /* Generate an index for each row. The index values will 
       go from 1 to n (the number of generated rows) for each row 
       in table1 */ 
      @i := if(@id = a.id, @i + 1, 1) i, 

      /* We keep a reference to the previous table1.id, so that 
       we can reset the counter when we move to the next row 
       in table1 */ 
      @id := a.id 
    FROM (
     /* Generate sufficient rows 
      You should have at least: Count(table1.*) x MAX_CSV_VALUES_PER_ROW rows */ 
     SELECT * 
     FROM table1 a 
     /* I used information_schema.global_status, but you may use any other table 
      or even create your own temporary table: 
      SELECT 1 UNION ALL SELECT 2 ... UNION ALL SELECT n */ 
     INNER JOIN information_schema.global_status b ON 1 = 1 
     ORDER BY a.id 
    ) a 
    INNER JOIN (SELECT @i := 0, @id := NULL) x 
) a 
WHERE 
    /* Keep only the relevant values; the other values are duplicates. 
     We're going to keep only those values with indices that are less 
     or equal to the number of CSV values in vals */ 
    i <= LENGTH(vals) - LENGTH(REPLACE(vals, ',', '')) + 1; 
+0

Vielen Dank für Ihre Hilfe –