0

我的表中有一个非规范化记录:

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 个代码。

4

2 回答 2

2

这是它的工作原理,包括测试数据等等。

考虑到这只是一个有趣的答案。要走的路显然是存储过程或函数或其他任何东西。

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;
于 2012-06-19T12:56:57.930 回答
1

甲骨文的方式是:

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。

于 2012-06-19T13:53:03.453 回答