pl sql正则表达式得到特定的出现

时间:2019-05-02 11:12:15

标签: sql regex oracle

我有一个这样的字符串:aa;bb;cc

每个块的字符数可以不同。

;是分隔符。

我需要分别取值。例如:我只想将出现的位置放在第二个位置(bb)。

我尝试过:

SELECT trim(regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL)) str
   FROM dual 
CONNECT BY regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL) IS NOT NULL;

但是,如果我这样做:

SELECT * FROM (SELECT trim(regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL)) str
   FROM dual 
CONNECT BY regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL) IS NOT NULL) 
  WHERE ROWNUM = 2; 

它不起作用。

3 个答案:

答案 0 :(得分:1)

您可以使用

with t(str) as
(
 select 'aa;bb;cc' from dual
), t2 as
(
select trim(regexp_substr(str, '[^;]+', 1, level)) str,
       level as lvl
   from t 
 connect by regexp_substr(str, '[^;]+', 1, level) is not null
) 
select str 
  from t2
 where lvl = 2;

STR
---
bb

Demo

我不建议您尽可能多地使用rownum,尤其是带有子查询和order by子句的查询。在您的情况下,WHERE ROWNUM = 1返回一个值(结果是不可信任的,我的意思是可能不是您想要的用于从表派生的实际值),而是返回了其他等式ROWNUM = 2ROWNUM = 3甚至不返回任何值。

答案 1 :(得分:1)

为什么不简单地写这个呢?

 select trim(regexp_substr('aa;bb;cc', '[^;]+', 1, 2)) str from dual 

如果要使用递归查询,请在内部查询中使用带有别名的rownum或使用level伪列:

select str 
  from (
    select level lvl, trim(regexp_substr('aa;bb;cc', '[^;]+', 1, 2)) str 
      from dual 
      connect by regexp_substr('aa;bb;cc', '[^;]+', 1, level) is not null)
  where lvl = 2

答案 2 :(得分:1)

WHERE ROWNUM = 2永远不会返回任何结果,因为rownum是根据查询的结果集计算得出的。但是由于永远不会有第一行,所以将永远不会达到ROWNUM = 2。

最简单的方法是使用OFFSET和LIMIT: SELECT * FROM ( SELECT trim(regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL)) str FROM dual CONNECT BY regexp_substr('aa;bb;cc', '[^;]+', 1, LEVEL) IS NOT NULL ) OFFSET 1 ROW FETCH NEXT 1 ROWS ONLY