0

テーブルに非正規化されたレコードがあります。

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

2番目の列には、|で区切られたvarcharフィールドに保存されたint値があります。シンボル。リンクテーブルを使用して、通常の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

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に適応できることを願っています。

于 2012-06-19T13:53:03.453 に答える