如何将IN运算符与LIKE条件相结合(或获得可比结果的最佳方法)

时间:2010-01-25 07:59:36

标签: sql sql-server oracle

我需要选择一个字段以几个不同前缀之一开头的行:

select * from table 
where field like 'ab%' 
  or field like 'cd%' 
  or field like "ef%" 
  or...

在Oracle或SQL Server中使用SQL执行此操作的最佳方法是什么?我正在寻找类似以下语句(不正确)的内容:

select * from table where field like in ('ab%', 'cd%', 'ef%', ...)

select * from table where field like in (select foo from bar)

编辑: 我想看看如何在一个SELECT语句中给出所有前缀,将所有前缀存储在一个帮助器表中。

前缀的长度不固定。

5 个答案:

答案 0 :(得分:16)

将您的前缀表与您的实际表连接在SQL Server&甲骨文。

DECLARE @Table TABLE (field VARCHAR(32))
DECLARE @Prefixes TABLE (prefix VARCHAR(32))

INSERT INTO @Table VALUES ('ABC')
INSERT INTO @Table VALUES ('DEF')
INSERT INTO @Table VALUES ('ABDEF')
INSERT INTO @Table VALUES ('DEFAB')
INSERT INTO @Table VALUES ('EFABD')

INSERT INTO @Prefixes VALUES ('AB%')
INSERT INTO @Prefixes VALUES ('DE%')

SELECT  t.*
FROM    @Table t
        INNER JOIN @Prefixes pf ON t.field LIKE pf.prefix 

答案 1 :(得分:6)

您可以尝试regular expression

SELECT * from table where REGEXP_LIKE ( field, '^(ab|cd|ef)' );

答案 2 :(得分:5)

如果您的前缀总是两个字符,您是否可以使用SUBSTRING()函数获取“field”的前两个字符,然后查看它是否在前缀列表中?

select * from table
where SUBSTRING(field, 1, 2) IN (prefix1, prefix2, prefix3...)

就简单而言,即使不是表现,这也是“最好的”。在性能方面,您可以创建一个索引虚拟列,从“字段”生成前缀,然后使用谓词中的虚拟列。

答案 3 :(得分:1)

根据数据集的大小,REGEXP解决方案可能是也可能不是正确答案。如果你想获得一小块大数据集,

select * from table   
where field like 'ab%'   
  or field like 'cd%'   
  or field like "ef%"   
  or... 

可以在幕后重写为

select * from table   
 where field like 'ab%'   
union all
select * from table
 where field like 'cd%'   
union all
select * from table
 where field like 'ef%' 

执行三次索引扫描而不是完整扫描。

如果你知道你只追求前两个字符,那么创建一个基于函数的索引也是一个很好的解决方案。如果您确实需要对此进行优化,请使用全局临时表来存储感兴趣的值,并在它们之间执行半连接:

select * from data_table
 where transform(field) in (select pre_transformed_field
                              from my_where_clause_table);

答案 4 :(得分:0)

你也可以尝试这样,这里 tmp 是由所需前缀填充的临时表。这是一种简单的方法,并且可以胜任。

select * from emp join 
(select 'ab%' as Prefix
union
select 'cd%' as Prefix
union
select 'ef%' as Prefix) tmp
on emp.Name like tmp.Prefix