在许多行中拆分列会产生太多行

时间:2014-12-09 08:53:37

标签: oracle

我正在尝试这个陈述

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个条目)时需要花费很长时间。 有人能提供更复杂的解决方案吗?

2 个答案:

答案 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 ;