Oracle SQL符号分隔的多行字符串拆分
来源:互联网 发布:出国语言软件 编辑:程序博客网 时间:2024/06/06 04:36
之前写了一篇文章,http://blog.csdn.net/seandba/article/details/72644257
讨论了从单行字符串拆分到多行字符串拆分,最后的解决不算圆满。
从一个比较简单的问题出发的,需求如下:
将源表的name列的字符串拆分成一个个字符,不使用union all等语法,因为数据量大了之后扩展性不好。
另外尽量使用一条sql语句,尽量简洁、高效
--小数据量+短字符串的情况select * from t;IDNAME1a2bb3cccselect id, split_chr from (select t.id, t.name, sys_connect_by_path(id, ',') path, regexp_substr(t.name, '.', 1, level) split_chr from t where regexp_substr(t.name, '.', 1, level) is not null connect by level <= 3) where regexp_like(path, '^(,.)\1{0,2}$');IDSPLIT_CHR1a2b2b3c3c3c以上sql解释请参考上篇文章,http://blog.csdn.net/seandba/article/details/72644257
虽然解决了上面的简化问题,但是还是存在一个最大的问题,这种写法不能扩展,当记录数稍微增多,字符串长度稍微增长,那就是无尽的等待。上面写法的致命缺陷是没有限制条件(prior xx=yy)的connect by,会导致巨大的连接。忽然间想到,用connect by的用意其实就是复制记录,把一个字符串长度为n的行复制出n行出来,然后结合level来截取即可。一直盯着层次查询、正则表达式,反而忽视了这个最重要的一点。基于以上分析,使用以下写法,扩展性也不错,我使用了100万条记录测试,每条字符串长度为26。基本上无需等待。
具体尝试如下:
--字符串拆分为字符drop table x purge;create table x as select level id, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' name from dualconnect by level <= 1000000;select id,regexp_substr(x.name, '.', 1, y.lv) split_chr from x, (select level lv from dual connect by level <= (select max(length(name)) level_depth_max from x)) y where length(x.name) >= y.lv;--符号分隔的字符串拆分(以逗号分隔为例) drop table x purge;create table x as select level id, 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z' name from dualconnect by level <= 1000000; select id,regexp_substr(x.name, '[^,]+', 1, y.lv) split_chr from x, (select level lv from dual connect by level <= (select max(regexp_count(name, '[^,]+')) level_depth_max from x)) y --此行下面有说明 where regexp_count(name, '[^,]+') >= y.lv;说明:这一行的查询做了一次全表扫描,目的是获取需要拆分列的实际最大长度,如果全表扫描代价太大,可以尝试直接赋值为本列的宽度。
--在另外一个地方看到这么一个写法,很有趣,使用(prior dbms_random.value is not null)消除了循环,也就是把我们上面讨论的(小数据量+短字符串的情况)之所以不能扩展的巨大的连接给消除了,所以也能支持大数据量和长字符串的拆分了--网址:http://www.itpub.net/thread-1803498-1-1.html 见网友hh7yx的回复--有兴趣可以比较下两种写法的执行计划和效率drop table x purge;create table x as select level id, 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z' name from dualconnect by level <= 1000000;select id, regexp_substr(x.name, '[^,]+', 1, level) split_chr from xconnect by id = prior id and prior dbms_random.value is not null and level <= regexp_count(name, '[^,]+');
总结,虽然可以通过pl/sql大而化小,或者通过编写函数处理,但是通过系统自带的函数和语法解决问题看起来还是非常简洁的。
阅读全文
0 0
- Oracle SQL符号分隔的多行字符串拆分
- oracle拆分逗号分隔的字符串
- 字符串按规定分隔符号拆分
- oracle 拆分逗号分隔字符串 实现split
- oracle 拆分逗号分隔字符串 实现split
- oracle拆分逗号分隔字符串 实现split
- oracle拆分逗号分隔字符串 实现split
- oracle拆分逗号分隔字符串 实现split
- oracle拆分逗号分隔字符串 实现split
- sql server 函数根据分隔符号拆分字符
- sqlserver 拆分逗号分隔的字符串
- 将一个以逗号分隔的字符串拆分单个记录,并生成插入sql语句
- oracle自定义函数按照某个分隔符拆分字符串
- sql 字符串按某分隔符拆分函数
- SQL Server 2005中拆分逗号分隔的字符串或把逗号分隔的字符串拆成数据表的函数
- SQL Server中自定义函数:用指定的分隔符号分割字符串
- 拆分以分隔符分割的单列为多列(行拆分)
- 基于《PythonCookbook》的学习(1)——针对任意多的分隔符拆分字符串
- 设计模式学习笔记——单例模式
- 数据结构与算法(27)——排序(二)
- RecyclerView系列(二)下拉刷新、上拉加载、Item点击监听
- DNS服务器的配置
- Javabean+JSP 实现文件的上传 显示 下载
- Oracle SQL符号分隔的多行字符串拆分
- ECOMP白皮书
- CEF 嵌入到MFC的流程,包括启动CEF以及CEF程序的关闭流程。
- #一.mybatis简介
- Github详解
- linux启动流程简介
- #二.mybatis-helloworld
- iframe 和 父页面 相互取值及函数调用
- 不解释,看图