2016-06-01 38 views
1

我在一個表REGEXP_SUBSTR其中條件

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

我想查詢中選擇特定PROC,像PROC1和procedure4有這樣的數據,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錯字錯誤,它的低位字母 – 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和我oppinion會更適合這裏。

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 

,如果你想獲得從表中的值,你可以使用Oracle提供的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 /使用正則表達式的子查詢的對是proc1|procedure4,這將是在前面的示例中需要的正則表達式需要

+0

我的例子中的數據是另一張表,'where in'會起作用嗎? – Moudiz

+0

@Moudiz我編輯了這個問題,所以它會動態生成正則表達式 – SomeJavaGuy

3

您不需要使用正則表達式來執行此操作。你只可以使用普通SUBSTRINSTR獲得從開始的子到第一/

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)