2016-04-15 64 views
1

我有一個表1:Mysql的分割線INSERT

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

...

通過SQL,我怎麼能分裂值插入到另一個表來獲得:

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

謝謝!

+2

過於複雜,不能只用SQL來完成,你必須包括至少一些存儲過程來做到這一點。最好通過一些服務器端腳本(如PHP)來實現,而解決方案不僅僅是簡單。 – mitkosoft

回答

0

這對你有幫助嗎? Split strings using mysql

如果「值」列中連接值的數量未知或不同,我會使用使用單獨函數(SPLIT_STR)的answer。否則它變得非常複雜。

0

這裏是你如何能做到這一點在MySQL:

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 

顯然,主要的問題是在第二列轉換爲行。

下面是它如何工作的(你應該開始從內部查詢閱讀它):

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

非常感謝您的幫助 –