我有一个这样的字符串: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;
它不起作用。
答案 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
我不建议您尽可能多地使用rownum
,尤其是带有子查询和order by子句的查询。在您的情况下,WHERE ROWNUM = 1
返回一个值(结果是不可信任的,我的意思是可能不是您想要的用于从表派生的实际值),而是返回了其他等式ROWNUM = 2
或ROWNUM = 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