REGEXP_SUBSTR在哪里有条件

时间:2016-06-01 07:11:22

标签: sql oracle

我在表格中有这些数据

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')

3 个答案:

答案 0 :(得分: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

另外,您可以使用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

如果您想从表中获取值,可以使用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 / P将是proc1|procedure4,这将是前面示例中所需的正则表达式

答案 1 :(得分: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 :(得分:2)

如果您设置的程序位于不同的表格中,则可以采用以下方式:

<强>设定:

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)