zoukankan      html  css  js  c++  java
  • 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
    )
    ;

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

  • 相关阅读:
    LeetCode 127. Word Ladder 单词接龙(C++/Java)
    LeetCode 681. Next Closest Time 最近时刻 / LintCode 862. 下一个最近的时间 (C++/Java)
    LeetCode 682. Baseball Game 棒球比赛(C++/Java)
    LeetCode 218. The Skyline Problem 天际线问题(C++/Java)
    小数据池,编码
    字典
    列表
    常见的数据类型
    while循环
    初始python
  • 原文地址:https://www.cnblogs.com/jiangqingfeng/p/9555975.html
Copyright © 2011-2022 走看看