我需要查找匹配所有查询短语但忽略其发生顺序的记录。
例如,我的查询字符串是apple banana kiwi
。以下值应该是真的。
I like apple, banana and kiwi
Banana, kiwi and apple are fruits
以下值应为false
He does not like kiwi
如何在Oracle 11中通过SQL实现?
答案 0 :(得分:2)
在现代正则表达式引擎中,您可以使用前瞻断言将这三个条件合并为一个表达式:
(?:.*?\bapple\b)(?:.*?\bbanana\b)(?:.*?\bkiwi\b)
但是,Oracle不支持预见,这意味着您无法编写同时检查所有三个条件的表达式(*)。
您的选择:
AND
组合在一起 - 这是最慢的变体,但它可以正常工作。LIKE
使用多个AND
子句 - 这会比正则表达式快一点,但相比之下表达复杂性有限。(*)从技术上讲,在学术上,你可以。您可以编写一个表达式来检查关键字的所有可能排列,例如
A.*?B.*?C|B.*?C.*?A|C.*?A.*?B|...and so on|and so forth
想想你是否会称这是一个可接受的解决方案。哦,是的,它也会很慢。
答案 1 :(得分:2)
这是一次尝试:
with w as -- The words
(
select 'apple banana kiwi' words from dual
),
p as -- the patterns taken from the words
(
select regexp_substr(w.words, '\w+', 1, level) pattern
from w
connect by regexp_substr(w.words, '\w+', 1, level) is not null
),
r as -- the phrases to test
(
select 'I like apple, banana and kiwi' phrase from dual
union all
select 'Banana, kiwi and apple are fruits' phrase from dual
union all
select 'He does not like kiwi' phrase from dual
)
select r.phrase
case sum(case instr(upper(r.phrase), upper(p.pattern))
when 0 then 0
else 1 end)
when regexp_count(w.words, '\w+', 1) then 'true'
else 'false' end all_present
from r, p, w
group by r.phrase, w.words
;
结果:
He does not like kiwi false
Banana, kiwi and apple are fruits true
I like apple, banana and kiwi true
原则:
instr
:如果为0,则不存在,否则为