我的表包含一个包含多个以逗号(,)分隔的值的列,并希望将其拆分,因此我将earch Site放在自己的行上,但前面的数字相同。
所以我的选择将来自此输入
table Sitetable
Number Site
952240 2-78,2-89
952423 2-78,2-83,8-34
创建此输出
Number Site
952240 2-78
952240 2-89
952423 2-78
952423 2-83
952423 8-34
我找到了一些我认为会起作用的东西但是没有......
select Number, substr(
Site,
instr(','||Site,',',1,seq),
instr(','||Site||',',',',1,seq+1) - instr(','||Site,',',1,seq)-1) Site
from Sitetable,(select level seq from dual connect by level <= 100) seqgen
where instr(','||Site,',',1,seq+1) > 0
Edit2:我看到我实际上有一部分工作选择(我是一个糟糕的测试人员:(),上面的一个工作,但唯一的问题是它失去了最后的网站值,但我试图工作有点......
Edit3:现在正在运作
select Number, substr(
Site,
instr(','||Site,',',1,seq),
instr(','||Site||',',',',1,seq+1) - instr(','||Site,',',1,seq)-1) Site
from Sitetable,(select level seq from dual connect by level <= 100) seqgen
where instr(','||Site,',',1,seq) > 0
答案 0 :(得分:4)
正确答案是。
select Number, substr(
Site,
instr(','||Site,',',1,seq),
instr(','||Site||',',',',1,seq+1) - instr(','||Site,',',1,seq)-1) Site
from Sitetable,(select level seq from dual connect by level <= 100) seqgen
where instr(','||Site,',',1,seq) > 0
答案 1 :(得分:3)
您是否尝试过Michael How to best split csv strings in oracle 9i
的答案?create or replace function splitter_count(str in varchar2, delim in char) return int as
val int;
begin
val := length(replace(str, delim, delim || ' '));
return val - length(str);
end;
create type token_list is varray(100) of varchar2(200);
CREATE or replace function tokenize (str varchar2, delim char) return token_list as
ret token_list;
target int;
i int;
this_delim int;
last_delim int;
BEGIN
ret := token_list();
i := 1;
last_delim := 0;
target := splitter_count(str, delim);
while i <= target
loop
ret.extend();
this_delim := instr(str, delim, 1, i);
ret(i):= substr(str, last_delim + 1, this_delim - last_delim -1);
i := i + 1;
last_delim := this_delim;
end loop;
ret.extend();
ret(i):= substr(str, last_delim + 1);
return ret;
end;
答案 2 :(得分:2)
------------创建结果表----------------------------- -------------- 强>
创建table resulTable(
cnumber number,
网站varchar2(1000)
);
------------创建拆分程序----------------------------- --------- 强>
/ 在这里我用数字代替数字:2-78由s2ss78s代替使用
DBMS_UTILITY.comma_to_table(它不适用于数字) /
创建或替换过程split_list_to_rows(num number,plist varchar2)为
ptablen BINARY_INTEGER;
ptab DBMS_UTILITY.uncl_array;
开始
DBMS_UTILITY.comma_to_table(
list =&gt;替换(替换(CONCAT('s',plist),',',',s'),' - ','ss'),
tablen =&gt; ptablen,
tab =&gt; PTAB);
FOR i IN 1 .. ptablen LOOP
插入INTO结果值(num,replace(ltrim(ptab(i),'s'),'ss',' - '));
END LOOP;
END;
------------ PL / SQL阻止每行执行程序-------------------
开始
for i in(select cnumber,Site from Sitetable)
环
split_list_to_rows(i.cnumber,i.Site);
结束循环;
端;
------------------------查看结果----------------- ---------------------- 强>
从resulTable中选择*;
答案 3 :(得分:0)
我认为您的最大限制为100个逗号分隔值,这是不必要的,但在您的情况下可能没有害处。
而不是
from Sitetable,(select level seq from dual connect by level <= 100)
这适用于任意数量的值(级别受限于最大逗号数)。
from Sitetable,(select level seq from dual connect by level <= (select max((LENGTH(site)-LENGTH(REPLACE(site,',', '' ))) + 1) from sitetable)
答案 4 :(得分:-1)
使用交叉连接:
选择编号,站点编号
从站点表
交叉应用STRING_SPLIT(Site,',');