oracle中分解逗号分隔的字符串

 ---------------------------------------------------------------------------------------------------------------------------------

 ------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
)
;

---------------------------------------------------------------------------------------------------------------------------------

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 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会报循环错误,所以要加.

转载于:https://www.cnblogs.com/jiangqingfeng/p/9555975.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值