我的表中有一个非规范化的记录:
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 :(得分: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 :(得分: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改编它。