sql >> Databáze >  >> RDS >> Oracle

Oracle dotaz k nalezení všech výskytů znaku v řetězci

Rozšířením odpovědi GolezTrol můžete použít regulární výrazy k výraznému snížení počtu rekurzivních dotazů, které děláte:

 select instr('SSSRNNSRSSR','R', 1, level)
   from dual
connect by level <= regexp_count('SSSRNNSRSSR', 'R')

REGEXP_COUNT() vrátí, kolikrát se vzor shoduje, v tomto případě kolikrát R existuje v SSSRNNSRSSR . To omezuje úroveň rekurze na přesné číslo, které potřebujete.

INSTR() jednoduše hledá index R ve vašem řetězci. level je hloubka rekurze, ale v tomto případě je to také úroveň th výskyt řetězce, protože jsme se omezili na požadovaný počet opakování.

Pokud je řetězec, který chcete vybrat, složitější, můžete použít regulární výrazy ans REGEXP_INSTR() na rozdíl od INSTR(), ale bude to pomalejší (ne o moc) a není to nutné, pokud to není nutné.

Jednoduchý benchmark podle požadavku:

Dvě řešení CONNECT BY naznačují, že použití REGEXP_COUNT je na řetězci této velikosti o 20 % rychlejší.

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

Funkce zřetězené tabulky je o něco pomalejší, i když by bylo zajímavé vidět, jak funguje na velkých řetězcích se spoustou shod.

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


  1. Jak vytvořit dotaz s group_concat na serveru SQL

  2. Získejte poslední ID vložky po připravené vložce s PDO

  3. MySQL ORDER BY IN()

  4. Chyba Postgres na insertu - CHYBA:neplatná sekvence bajtů pro kódování UTF8:0x00