我在表格中有这些数据
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')
答案 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)
您不需要使用正则表达式来执行此操作。您可以使用普通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 :(得分: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)