---------------------------------------------------------------------------------------------------------------------------------
------2019.1.17 11:58发现 subs与danoutyear的值一样的
select aac001,outyear,substr(outyear,instr(outyear,'|',1,ceng)+1,instr(outyear,'|',1,ceng+1)-instr(outyear,'|',1,ceng)-1) subs
,regexp_substr(outyear_ys,'[^|]+',1,ceng) danoutyear
,'1' flag from (
select aac001,'|'||outyear||'|' outyear,level ceng,outyear outyear_ys from (
select residence_id as aac001,aid_yr as outyear,return_poor_yr as retyear from 户表 where 时间=20161231 and aid_yr is not null
)
connect by level<=regexp_count('|'||outyear,'[|]') and aac001=prior aac001 and prior dbms_random.value is not null
)
;
2020.1.14 17:42发现还能更简单写,参照下文的 更简单的方法,不用子查询,可一个sql
---------------------------------------------------------------------------------------------------------------------------------
drop table cs_thz_1 ;
create table cs_thz_1( nid number(10) ,sname varchar2(1000) );
truncate table cs_thz_1;
insert into cs_thz_1(nid,sname)
select 1,'苹果,香蕉' from dual union all select 2,'茄子,豆角,西蓝花,芥蓝' from dual union all select 3,'笔' from dual ;
commit;
--sname确保两边都有逗号才能分隔
select nid,sname,cnt,level
,substr(sname, instr(sname,',',1,level) + 1 , instr(sname, ',', 1, level + 1) - instr(sname, ',', 1, level) - 1) s2
from (
select nid,','||sname||',' as sname,length(','||sname)-length(replace(','||sname,',')) cnt from cs_thz_1--sname确保两边都有逗号
) connect by prior nid = nid and level <= cnt and prior dbms_random.value is not null ;
更简单的方法
select nid,sname,regexp_substr(sname,'[^,]+',1,level) as str
from cs_thz_1 where sname is not null
connect by level<=(nvl(regexp_count(sname,','),0)+1) and prior nid=nid and prior dbms_random.value is not null
;
select instr(s1,',',1,5) from (--没有第5个逗号则返回0
select '1,2,3,4,5' s1 from dual
) ;
或
with tmp_a as (
select 1 nid,'ar,brt,city,eight' str from dual union all
select 2,'air' from dual union all
select 3,'a,b' from dual
)
select ceng,nid,str,substr(str,instr(str,',',1,ceng)+1,instr(str,',',1,ceng+1)-instr(str,',',1,ceng)-1)
from (
select level ceng,nid,','||str||',' as str from tmp_a connect by level<=(regexp_count(','||str,',')) and nid=prior nid and prior dbms_random.value is not null
)
;
---------------------------------------引用博客内容-------------------------------------------------
详细见:http://blog.sina.com.cn/s/blog_4cef5c7b0102v2in.html
如果多行字符串拆分,必然遇到与展开行同样的问题,方法也是可以用构造数据然后关联和DBMS_RANDOM.VALUE。如下:
1)使用传统数据构造方法 SELECT ID,rn,list_str,REGEXP_SUBSTR(list_str,'[^,]+',1,rn) str FROM t,(SELECT LEVEL rn FROM DUAL CONNECT BY LEVEL<=(SELECT MAX(length(trim(translate(list_str,replace(list_str,','),' '))))+1 FROM t)) WHERE REGEXP_SUBSTR(list_str,'[^,]+',1,rn) IS NOT NULL ORDER BY ID,rn;
2)使用DBMS_RANDOM递归技巧 SELECT id,level lv,list_str, rtrim(regexp_substr(list_str || ',', '.*?' || ',', 1, LEVEL), ',') AS str FROM t CONNECT BY id = PRIOR id AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL AND LEVEL <= length(regexp_replace(list_str, '[^,]'))+1 ORDER BY ID,lv ;
结果都是: ID LV LIST_STR STR ---- ---------- -------------------- ---------- 1 1 xyy,m,ab xyy 1 2 xyy,m,ab m 1 3 xyy,m,ab ab 2 1 o,pn,nnnn,bb o 2 2 o,pn,nnnn,bb pn 2 3 o,pn,nnnn,bb nnnn 2 4 o,pn,nnnn,bb bb 3 1 M M
---------------------------------connect by 层级查询----------------------------------------------
select * from (
select nid,str,level from (
select 1 nid,'a,b,c' str from dual union all
select 2 nid,'1,a,三' str from dual union all
select 3 nid,'e,f,g' str from dual union all
select 4 nid,'r,s,t' str from dual
) connect by level<=2
)
;
4条都展开2层,第1层4条,第2层4+4+4+4=16条,所以共显示20条.
select * from (
select nid,str,level from (
select 1 nid,'a,b,c' str from dual union all
select 2 nid,'1,a,三' str from dual union all
select 3 nid,'e,f,g' str from dual union all
select 4 nid,'r,s,t' str from dual
) connect by nid=prior nid and level<=2 and prior dbms_random.value is not null
)
;
这句要求第2层的nid=第1层的nid,所以每行显示2次,不加prior dbms_random.value is not nul会报循环错误,所以要加.