在Oracle IN子句中使用LIKE

问题描述 投票:16回答:8

我知道我可以编写一个查询,该查询将返回给定列中包含任意数量值的所有行,如下所示:

Select * from tbl where my_col in (val1, val2, val3,... valn)

但是,例如,如果val1可以出现在my_col的任何地方,其数据类型为varchar(300),我可以改写为:

select * from tbl where my_col LIKE '%val1%'

是否有结合这两种技术的方法。我需要搜索可能出现在该列的自由格式文本中任何地方的大约30个值。

以以下方式组合这两个语句似乎不起作用:

select * from tbl where my_col LIKE ('%val1%', '%val2%', 'val3%',....) 

select * from tbl where my_col in ('%val1%', '%val2%', 'val3%',....)
sql oracle sql-like
8个回答
30
投票
select * from tbl 
where my_col like '%val1%' or my_col like'%val2%' or my_col like '%val3%', ...

但是请注意,这可能会很慢...或者,您可以将所有可接受的值(包括%符号)插入表中并半联接该表:

select * from tbl
where exists (select 1 from all_likes where tbl.my_col like all_likes.value)

对于真正的全文搜索,您可能希望查看Oracle Text:

http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html


7
投票

不,您不能这样做。 IN子句中的值必须完全匹配。您可以这样修改选择:

SELECT *
  FROM tbl
 WHERE my_col LIKE %val1%
    OR my_col LIKE %val2%
    OR my_col LIKE %val3%
 ...

如果val1,val2,val3 ...足够相似,则可以在REGEXP_LIKE运算符中使用正则表达式。


4
投票

REGEXP_LIKE将执行不区分大小写的正则表达式搜索。

select * from Users where Regexp_Like (User_Name, 'karl|anders|leif','i')

此操作将作为全表扫描执行-与LIKE or解决方案一样,因此,如果表不小,性能将[变差。如果根本不经常使用它,那可能没问题。

如果需要某种性能,则需要

Oracle Text

(或某些外部索引器)。 要使用Oracle Text获得子字符串索引,您将需要CONTEXT索引。它涉及很多方面,因为它是使用许多智能工具为大型文档和文本建立索引而创建的。如果您有特殊需要,例如数字和所有单词(包括“ the”,“ an”,“ a”,空格等)的子字符串搜索,则需要创建自定义词法分析器以删除某些智能内容...

如果插入大量数据,Oracle Text将不会使事情变得更快,特别是如果您需要在事务内而不是定期更新索引的时候。


2
投票
这个非常快:

select * from listofvalue l inner join tbl on tbl.mycol like '%' || l.value || '%'


2
投票
是,您可以使用此查询(代替'Specialist''Developer',键入要用逗号分隔的任何字符串,并用表更改employees表)

SELECT * FROM employees em WHERE EXISTS (select 1 from table(sys.dbms_debug_vc2coll('Specialist', 'Developer')) mt where em.job like ('%' || mt.column_value || '%'));

为什么我的查询比接受的答案更好:您不需要CREATE TABLE权限即可运行它。只需SELECT权限即可执行。

1
投票
select * from tbl where exists (select 1 from all_likes where all_likes.value = substr(tbl.my_col,0, length(tbl.my_col)))

1
投票
只需添加@Lukas Eder的答案。

避免创建表和插入值的改进(我们可以使用select from dualunpivot即时获得相同的结果):

with all_likes as (select * from (select '%val1%' like_1, '%val2%' like_2, '%val3%' like_3, '%val4%' as like_4, '%val5%' as like_5 from dual) unpivot ( united_columns for subquery_column in ("LIKE_1", "LIKE_2", "LIKE_3", "LIKE_4", "LIKE_5")) ) select * from tbl where exists (select 1 from all_likes where tbl.my_col like all_likes.united_columns)


1
投票
我喜欢这个

WHERE CASE WHEN my_col LIKE '%val1%' THEN 1 WHEN my_col LIKE '%val2%' THEN 1 WHEN my_col LIKE '%val3%' THEN 1 ELSE 0 END = 1

我并不是说它是最佳的,但是它可以工作,而且很容易理解。我的大多数查询都是临时使用的,因此性能通常对我来说不是问题。
© www.soinside.com 2019 - 2024. All rights reserved.