所有行擴展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