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

  • 相关阅读:
    Dot Net WinForm 控件开发 (七) 为属性提下拉式属性编辑器
    WinForm 程序的界面多语言切换
    c#遍历HashTable
    Dot Net WinForm 控件开发 (三) 自定义类型的属性需要自定义类型转换器
    Dot Net WinForm 控件开发 (六) 为属性提供弹出式编辑对话框
    Dot Net WinForm 控件开发 (一) 写一个最简单的控件
    Dot Net WinForm 控件开发 (四) 设置属性的默认值
    Dot Net WinForm 控件开发 (二) 给控件来点描述信息
    Dot Net WinForm 控件开发 (八) 调试控件的设计时行为
    Dot Net WinForm 控件开发 (五) 复杂属性的子属性
  • 原文地址:https://www.cnblogs.com/jiangqingfeng/p/9555975.html
Copyright © 2011-2022 走看看