2012-06-19 87 views
0

我有我的表去歸一化的記錄:MySQL的:分裂VARCHAR值和插入件

ID, CODES 
1 |1|2|3|4 
2 |5|6|7|8 

在第二列有int類型,保存在由分離varchar字段|符號。 我想使用鏈接表將它們轉換爲正常的Many2Many關係表。 所以我想創建一個表像這樣

ID CODE 
1 1 
1 2 
1 3 
1 4 
.... 
2 8 

我明白,我可以通過在MySQL存儲功能,分割字符串,並插入值記錄迭代。但我很感興趣:是否有可能以這種方式轉換數據沒有存儲過程/函數,但只使用查詢(創建表...選擇...)? 謝謝。

UPD:在不同行中有可變數量的代碼。每行有1到15個代碼。

+0

一個單元中的最大代碼數是多少? – biziclop

+0

代碼字段中只有四個「列」還是可變的?你的例子只顯示4「|」分隔的領域。 –

+0

@biziclop在不同的行中有可變數量的代碼。每行有1到15個代碼。 – dbf

回答

1

以下是它的工作原理,包含的測試數據等。

認爲,這僅僅是一個樂趣答案。要走的路線顯然是存儲過程或功能或其他。

drop table testvar; 
create table testvar (id int, codes varchar(20)); 
insert into testvar values (1, '|1|2|3|4'), (2, '|5|6|7|8'); 



drop table if exists inserttest; 
create table inserttest (id int, code int); 

select @sql:=left(concat('insert into inserttest values ', group_concat('(', id, ',', replace(right(codes, length(codes) - 1), '|', concat('),(', id, ',')), '),' separator '')), length(concat('insert into inserttest values ', group_concat('(', id, ',', replace(right(codes, length(codes) - 1), '|', concat('),(', id, ',')), '),' separator ''))) -1) 
from testvar; 

prepare stmt1 from @sql; 
execute stmt1; 

select * from inserttest; 
1

Oracle的方式是:

insert into newtestvar 
select t.id, to_number(substr(t.codes, p1 + 1, p2)) 
from (
    select testvar.id, testvar.codes, s.num, 
    instr(testvar.codes, '|',1,s.num) p1, 
    instr(testvar.codes||'|', '|',1,s.num + 1)- instr(testvar.codes, '|',1,s.num) - 1 p2 
    from testvar, (select level num from dual connect by level <= 15) s 
    where s.num <= (length(testvar.codes)-length(replace(testvar.codes, '|'))) 
) t; 

我希望你能適應它爲MySQL。