微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle 正则表达式行转列

原始的数据:

aa,bb,cc,dd

ee,ff,gg,hh

想要得到的结果:

aa

bb

cc

dd

...

先弄一条试试:

sql> with t as(

select 1 id,'aa,dd' names from dual
)
select id,REGEXP_SUBSTR(names,'[^,]+',1,level) name,
'REGEXP_SUBSTR('''||names|| ',''[^,]+'','||level||')' exec_s from t
connect by level <=regexp_count(names,',')+1
order by name;
ID NAME EXEC_S
---- ------ --------------------------------------------
1 aa REGEXP_SUBSTR('aa,dd,1)
1 bb REGEXP_SUBSTR('aa,2)
1 cc REGEXP_SUBSTR('aa,3)
1 dd REGEXP_SUBSTR('aa,4)
已用时间: 00: 00: 00.01


这么写发现结果集不对:

sql> with t as(
select 1 id,dd' names from dual
union all
select 2 id,'ee,hh' names from dual
)
select id,
'REGEXP_SUBSTR('''||names|| ',')+1
order by name;
ID NAME EXEC_S
--- ------ ----------------------------------------------
1 aa REGEXP_SUBSTR('aa,2)
1 bb REGEXP_SUBSTR('aa,3)
1 cc REGEXP_SUBSTR('aa,4)
1 dd REGEXP_SUBSTR('aa,4)
2 ee REGEXP_SUBSTR('ee,hh,1)
2 ff REGEXP_SUBSTR('ee,2)
2 ff REGEXP_SUBSTR('ee,2)
2 gg REGEXP_SUBSTR('ee,3)
2 gg REGEXP_SUBSTR('ee,3)
2 hh REGEXP_SUBSTR('ee,4)
2 hh REGEXP_SUBSTR('ee,4)
已选择30行。

已用时间: 00: 00: 00.06

原因是多行的话产生了上下级关系:

sql> with t as(
select 1 id,hh' names from dual
) select level,names,sys_connect_by_path(id,'--') as full_path,
count(1) over(partition by names,level) as cnt
from t
connect by level <= regexp_count(names,')+1
order by names,level;
LEVEL NAMES FULL_PATH CNT
---------- ----------- -------------------- ----------
1 aa,dd --1 1
2 aa,dd --2--1 2
2 aa,dd --1--1 2
3 aa,dd --1--2--1 4
3 aa,dd --1--1--1 4
3 aa,dd --2--2--1 4
3 aa,dd --2--1--1 4
4 aa,dd --1--1--2--1 8
4 aa,dd --1--1--1--1 8
4 aa,dd --2--2--2--1 8
4 aa,dd --2--2--1--1 8
4 aa,dd --2--1--2--1 8
4 aa,dd --2--1--1--1 8
4 aa,dd --1--2--2--1 8
4 aa,dd --1--2--1--1 8
1 ee,hh --2 1
2 ee,hh --1--2 2
2 ee,hh --2--2 2
3 ee,hh --2--2--2 4
3 ee,hh --2--1--2 4
3 ee,hh --1--2--2 4
3 ee,hh --1--1--2 4
4 ee,hh --1--1--1--2 8
4 ee,hh --1--2--1--2 8
4 ee,hh --2--2--2--2 8
4 ee,hh --1--2--2--2 8
4 ee,hh --2--1--2--2 8
4 ee,hh --2--1--1--2 8
4 ee,hh --2--2--1--2 8
4 ee,hh --1--1--2--2 8
只限制本行拆分:

sql> with t as(
select 1 id,dd' names from dual
union all
select 2 id,hh' names from dual
)
select level,level) as cnt from t
connect by prior names=names
and level<=regexp_count(names,')+1
and prior SYS_GUID() is not null;
LEVEL NAMES FULL_PATH CNT
---------- ----------- -------------------- ----------
1 aa,dd --1 1
2 aa,dd --1--1 1
3 aa,dd --1--1--1 1
4 aa,dd --1--1--1--1 1
1 ee,hh --2 1
2 ee,hh --2--2 1
3 ee,hh --2--2--2 1
4 ee,hh --2--2--2--2 1

改写:

sql> with t as(
select 1 id,'||level||')' exec_s from t
connect by prior names=names
and level<=regexp_count(names,')+1
and prior SYS_GUID() is not null order by name; ID NAME EXEC_S ---- ------- --------------------------------------------- 1 aa REGEXP_SUBSTR('aa,1) 1 bb REGEXP_SUBSTR('aa,2) 1 cc REGEXP_SUBSTR('aa,3) 1 dd REGEXP_SUBSTR('aa,4) 2 ee REGEXP_SUBSTR('ee,1) 2 ff REGEXP_SUBSTR('ee,2) 2 gg REGEXP_SUBSTR('ee,3) 2 hh REGEXP_SUBSTR('ee,4) 已选择8行。 已用时间: 00: 00: 00.05

原文地址:https://www.jb51.cc/oracle/209626.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐