2016-04-15 96 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

非常感谢您的帮助 –