2016-06-01 2 views
1

У меня есть эти данные в таблицеREGEXP_SUBSTR где в состоянии

procedure1/loc1/p1 
proc2/loc1/p2/c1 
proc1/loc2/p2/c2 
procedure3/loc1/p1 
procedure4/loc3/p1 

Я хочу запрос, чтобы выбрать конкретный процедурный, как proc1 и процедуры4, like не работал бы так ouptput должно быть, как это

proc1/loc2/p2/c2 
procedure4/loc3/p1 

Я попытался использовать REGEXP_SUBSTR, но как включить список процедуры, которую я хочу?

--this is wrong 
select * from tab1 where REGEXP_SUBSTR(col1, 
'[^/]+', 1, 1) in ('proc1','procedure4') 
+1

Измените 'PROC1' на 'proc1'.и ваш запрос должен работать. –

+0

@ ArkadiuszŁukasiewicz typo error, его нижняя буква – Moudiz

ответ

4

вы можете проверить, если длина возвращаемый REGEXP_SUBSTR больше 0

select * 
from (select 'procedure1/loc1/p1' a from dual union 
     select 'proc2/loc1/p2/c1' from dual union 
     select 'proc1/loc2/p2/c2' from dual union 
     select 'procedure3/loc1/p1' from dual union 
     select 'procedure4/loc3/p1' from dual) t 
where length(regexp_substr(t.a, 'procedure4|proc1')) > 0 

Alternativly можно использовать REGEXP_LIKE, который не просто возвращал boolean и на мой взгляд подошла бы лучше.

select * 
from (select 'procedure1/loc1/p1' a from dual union 
     select 'proc2/loc1/p2/c1' from dual union 
     select 'proc1/loc2/p2/c2' from dual union 
     select 'procedure3/loc1/p1' from dual union 
     select 'procedure4/loc3/p1' from dual) t 
where regexp_like(t.a, 'procedure4|proc1') 

O/P

proc1/loc2/p2/c2 
procedure4/loc3/p1 

, если вы хотите, чтобы получить значения из таблицы вы можете создать регулярное выражение динамически с помощью функции listagg предоставленной оракула. Теперь происходит то, что каждое возможное значение, которое могло бы произойти, объединяется с |, которое представляет собой or в регулярном выражении. Благодаря этому вы вы не в потребности в in, потому что ваше регулярное выражение будет иметь каждое возможное значение разделенного or

select * 
from (select 'procedure1/loc1/p1' a from dual union 
     select 'proc2/loc1/p2/c1' from dual union 
     select 'proc1/loc2/p2/c2' from dual union 
     select 'procedure3/loc1/p1' from dual union 
     select 'procedure4/loc3/p1' from dual) t 
where regexp_like(t.a, (select listagg(regexp.b, '|') WITHIN GROUP (ORDER BY regexp.b) regex 
         from (select 'procedure4' b from dual union 
           select 'proc1'  from dual) regexp)) 

O/P подзапроса, используемый для регулярных выражений будет proc1|procedure4, который был бы регулярное выражение, как показано в предыдущем примере

+0

данные в моем случае - другая таблица, 'where in' будет работать? – Moudiz

+0

@Moudiz я редактировал вопрос, чтобы он генерировал регулярное выражение динамически – SomeJavaGuy

3

Для этого не нужно использовать регулярные выражения. Вы просто могли бы использовать обычный SUBSTR и INSTR, чтобы получить подстроку от начала до первого /:

WITH your_table AS ( 
    SELECT 'procedure1/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'proc2/loc1/p2/c1' procedure_name FROM dual 
    UNION 
    SELECT 'proc1/loc2/p2/c2' procedure_name FROM dual 
    UNION 
    SELECT 'procedure3/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'procedure4/loc3/p1' procedure_name FROM dual 
) 
SELECT * 
FROM your_table 
WHERE SUBSTR(procedure_name,1,INSTR(procedure_name,'/')-1) IN ('proc1','procedure4'); 

Однако, если вы хотите узнать, как использовать регулярные выражения в Oracle. Вы можете использовать REGEXP_SUBSTR так:

WITH your_table AS ( 
    SELECT 'procedure1/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'proc2/loc1/p2/c1' procedure_name FROM dual 
    UNION 
    SELECT 'proc1/loc2/p2/c2' procedure_name FROM dual 
    UNION 
    SELECT 'procedure3/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'procedure4/loc3/p1' procedure_name FROM dual 
) 
SELECT * 
FROM your_table 
WHERE REGEXP_SUBSTR(procedure_name,'^(.+?)/',1,1,'i',1) IN ('proc1','procedure4'); 

Последний параметр указывает Oracle вернуть матч за шаблон между().

Как уже упоминалось, вы также можете использовать REGEXP_LIKE:

WITH your_table AS ( 
    SELECT 'procedure1/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'proc2/loc1/p2/c1' procedure_name FROM dual 
    UNION 
    SELECT 'proc1/loc2/p2/c2' procedure_name FROM dual 
    UNION 
    SELECT 'procedure3/loc1/p1' procedure_name FROM dual 
    UNION 
    SELECT 'procedure4/loc3/p1' procedure_name FROM dual 
) 
SELECT * 
FROM your_table 
WHERE REGEXP_LIKE(procedure_name,'^(proc1|procedure4)/'); 
2

Если процедуры вы interesetd в в другой таблице, один путь может быть следующим:

Установка:

CREATE TABLE your_table (col) AS 
    (SELECT 'procedure1/loc1/p1' FROM DUAL UNION ALL 
    SELECT 'proc2/loc1/p2/c1' FROM DUAL UNION ALL 
    SELECT 'proc1/loc2/p2/c2' FROM DUAL UNION ALL 
    SELECT 'procedure3/loc1/p1' FROM DUAL UNION ALL 
    SELECT 'procedure4/loc3/p1' FROM DUAL 
    ) 


CREATE TABLE procedures (name) AS 
    (SELECT 'proc1'  FROM DUAL UNION ALL 
    SELECT 'procedure4' FROM DUAL 
    ) 

Вы можете попробовать это, без каких-либо регулярных выражений:

SELECT * 
    FROM your_table 
    INNER JOIN procedures 
     ON (INSTR(col, name) != 0) 
Смежные вопросы