我正在尝试这个陈述
with value_table as
(select 1 id, '1/2/3' objnr from dual
union all
select 2, '4/5/6' from dual),
test as
(select id, objnr col from value_table where id in (1, 2))
select id, regexp_substr(col, '[^/]+', 1, level) result
from test
connect by level <= length(regexp_replace(col, '[^/]+')) + 1
order by 1
我想获得6行
1 1
1 2
1 3
2 4
2 5
2 6
但我多次获取这些行。 当我只用一个id尝试它时,它没有问题。 作为一种解决方法,我只为每个id创建一个循环,另一个解决方案是使用distinct,但是当我尝试使用真实数据(超过1000个条目)时需要花费很长时间。 有人能提供更复杂的解决方案吗?
答案 0 :(得分:1)
尝试使用下面的
with value_table as
(select 1 id, '1/2/3' objnr from dual
union all
select 2, '4/5/6' from dual),
test as
(select id, objnr col from value_table where id in (1, 2))
select distinct id, regexp_substr(col, '[^/]+', 1, level) result
from test
connect by level <= regexp_count(col, '[^/]+')
order by 1
尝试使用sqlfiddle http://sqlfiddle.com/#!4/03d80/14
修改强>
如果你不想要分别尝试下面的
with value_table as
(select 1 id, '1/2/3' objnr from dual
union all
select 2, '4/5/6' from dual),
test as
(select id, objnr col from value_table where id in (1, 2))
select id, regexp_substr(col, '[^/]+', 1, level) result
from test
connect by level <= regexp_count(col, '[^/]+')
and id = prior id
and prior dbms_random.value is not null
order by 1
使用模型子句PRIOR
sqlfiddle链接为http://sqlfiddle.com/#!4/03d80/31
答案 1 :(得分:1)
执行此查询
with test as
(
select 1 id, '1/2/3' objnr from dual union all
select 2 id, '4/5/6' objnr from dual
)
select id, regexp_substr (objnr, '[^/]+', 1, rn) result
from test
cross
join (select rownum rn
from (select max (length (regexp_replace (objnr, '[^/]+'))) + 1 mx
from test
)
connect by level <= mx
)
where regexp_substr (objnr, '[^/]+', 1, rn) is not null
and id in (1, 2)
order by id,result ;
ID结果
1 1
1 2
1 3
2 4
2 5
2 6
如果您使用的是Oracle 11g,您还可以使用REGEXP_COUNT而不是REGEXP_REPLACE和LENGTH的组合,如下所示:
cross
join (select rownum rn
from (select max (regexp_count (objnr, '/') + 1) mx
from test
)
connect by level <= mx
)
具有外连接行为,因此如下所示略有变化:
with test as
(
select 1 id, '1/2/3' objnr from dual union all
select 2 id, '4/5/6' objnr from dual
)
select id, regexp_substr (objnr, '[^/]+', 1, rn) result
from test
left outer join (select rownum rn
from (select max (regexp_count (objnr, '/') + 1) mx
from test
)
connect by level <= mx
) splits
ON splits.rn <= length(regexp_replace (objnr, '[^/]+'))+1
and id in (1, 2)
order by id,result ;