Regexp или substr или другой метод поиска строки

Я хочу добиться наилучшей производительности и выбрать "строку" только после слова "DL:"

У меня есть столбец (varchar2) со значениями:

    DL:1011909825
    Obj:020190004387 DL:8010406429
    Obj:020190004388 DL:8010406428
    DL:190682
    DL:PDL01900940
    Obj:020190004322 DL:611913067

поэтому вывод будет таким:

    1011909825
    8010406429
    8010406428
    190682
    PDL01900940
    611913067

Я не эксперт в регулярных выражениях, но я попробовал regexp_replace:

regexp_replace(column,'Obj:|DL:','',1, 0, 'i')

Это почти нормально, но результат все еще не тот:

    1011909825
    020190004387 8010406429
    020190004388 8010406428
    190682
    PDL01900940
    020190004322 611913067

Как я могу решить эту проблему и достичь наилучшего результата?

Может ли Obj: подписаться на DL:? У вас есть DL:1011909825 Obj:020190004387 подобные ценности? «Лучший» подход зависит от того, насколько беспорядочны ваши данные и нужно ли вам «предварительно проверять» свой вывод или нет.

Wiktor Stribiżew 09.04.2019 10:51
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
1
76
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Если данные всегда выглядят так, то SUBSTR + INSTR выполните задание:

SQL> with test (col) as
  2    (
  3      select 'DL:1011909825' from dual union all
  4      select 'Obj:020190004387 DL:8010406429' from dual union all
  5      select 'Obj:020190004388 DL:8010406428' from dual union all
  6      select 'DL:190682' from dual union all
  7      select 'DL:PDL01900940' from dual union all
  8      select 'Obj:020190004322 DL:611913067' from dual
  9     )
 10  select col, substr(col, instr(col, 'DL:') + 3) result
 11  from test;

COL                            RESULT
------------------------------ ------------------------------
DL:1011909825                  1011909825
Obj:020190004387 DL:8010406429 8010406429
Obj:020190004388 DL:8010406428 8010406428
DL:190682                      190682
DL:PDL01900940                 PDL01900940
Obj:020190004322 DL:611913067  611913067

6 rows selected.

SQL>

REGEXP_SUBSTR может выглядеть так:

 <snip>
 10  select col,
 11         ltrim(regexp_substr(col, 'DL:\w+'), 'DL:') resul
 12  from test;

COL                            RESULT
------------------------------ -----------------------------
DL:1011909825                  1011909825
Obj:020190004387 DL:8010406429 8010406429
Obj:020190004388 DL:8010406428 8010406428
DL:190682                      190682
DL:PDL01900940                 PDL01900940
Obj:020190004322 DL:611913067  611913067

Если данных много, это должно быть быстрее, чем регулярные выражения.

substr + instr будет иметь лучшую производительность, но если вы хотите использовать регулярное выражение:

-- substr + instr will have better performance
with s (str) as (
select 'DL:1011909825' from dual union all
select 'Obj:020190004387 DL:8010406429' from dual union all
select 'Obj:020190004388 DL:8010406428' from dual union all
select 'DL:190682' from dual union all
select 'DL:PDL01900940' from dual union all
select 'Obj:020190004322 DL:611913067' from dual)
select str, regexp_substr(str, 'DL:(.*)', 1, 1, null, 1) rs
from s;

STR                            RS                            
------------------------------ ------------------------------
DL:1011909825                  1011909825                    
Obj:020190004387 DL:8010406429 8010406429                    
Obj:020190004388 DL:8010406428 8010406428                    
DL:190682                      190682                        
DL:PDL01900940                 PDL01900940                   
Obj:020190004322 DL:611913067  611913067                     

6 rows selected.

Это DL:(.*) не показывает преимущества использования регулярных выражений, оно делает именно то, что делает решение Littlefoot без регулярных выражений.

Wiktor Stribiżew 09.04.2019 10:58

Вы можете получить некоторое представление об этом.

DL:(.*)

Match 1
1.  1011909825
Match 2
1.  8010406429
Match 3
1.  8010406428
Match 4
1.  190682
Match 5
1.  PDL01900940
Match 6
1.  611913067

https://rubular.com/r/jKjcPs8sPr4Ifn

В качестве альтернативы используйте regexp_substr :

with t(str) as
(
 select 'DL:1011909825'                  from dual union all
 select 'Obj:020190004387 DL:8010406429' from dual union all
 select 'Obj:020190004388 DL:8010406428' from dual union all
 select 'DL:190682'                      from dual union all
 select 'DL:PDL01900940'                 from dual union all
 select 'Obj:020190004322 DL:611913067'  from dual 
) 
select regexp_substr(str, '[^DL:]+$') as str
  from t;

STR
----------
1011909825
8010406429
8010406428
190682
01900940
611913067

Demo

Другие вопросы по теме