所有行扩展GolezTrol的回答,您可以使用正则表达式来显著减少你做递归查询的数量的事情:
select instr('SSSRNNSRSSR','R', 1, level)
from dual
connect by level <= regexp_count('SSSRNNSRSSR', 'R')
REGEXP_COUNT()返回模式匹配的次数,在这种情况下,SSSRNNSRSSR
中存在R
的次数。这将递归级别限制为您需要的确切数量。
INSTR()只需搜索字符串中的R索引。 level
是递归的深度,但在这种情况下,它也是th字符串的发生,因为我们限制为所需递归的数量。
如果你想挑选的字符串比较复杂,你可以使用正则表达式ans REGEXP_INSTR()而不是INSTR(),但是它会比较慢(不会太多),除非需要,否则它是不必要的。根据要求
简单的基准:
两个CONNECT BY解决方案将表明,使用REGEXP_COUNT是20%,快于这种规模的字符串。
SQL> set timing on
SQL>
SQL> -- CONNECT BY with REGEX
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select instr('SSSRNNSRSSR','R', 1, level)
7 bulk collect into t_num
8 from dual
9 connect by level <= regexp_count('SSSRNNSRSSR', 'R')
10 ;
11 end loop;
12 end;
13/
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.94
SQL>
SQL> -- CONNECT BY with filter
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select pos
7 bulk collect into t_num
8 from (select substr('SSSRNNSRSSR', level, 1) as character
9 , level as pos
10 from dual t
11 connect by level <= length('SSSRNNSRSSR'))
12 where character = 'R'
13 ;
14 end loop;
15 end;
16/
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.80
流水线表函数是一个公平的有点慢,但它会看到它如何执行过,有很多场比赛的大串很有趣。
SQL> -- PIPELINED TABLE FUNCTION
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select *
7 bulk collect into t_num
8 from table(string_indexes('SSSRNNSRSSR','R'))
9 ;
10 end loop;
11 end;
12/
PL/SQL procedure successfully completed.
Elapsed: 00:00:06.54
来源
2013-07-28 08:51:10
Ben
有趣的挑战。这将成为一个非常奇怪的查询,或者你将不得不编写一个存储过程。或者总是有最后的,不幸的可能性,有一些方便的功能,我不知道... – GolezTrol
(自写)功能可能比使用任何种类的递归查询更有效。 –
@a_horse_with_no_name - 它可能是,但不要低估调用函数的开销。不过,这将是一个有趣的测试,但目前我只有sqlfiddle,我怀疑这是否是一个可靠的基准测试平台。 – GolezTrol