如何将 IN 运算符与 LIKE 条件相结合(或获得可比较结果的最佳方法)
Posted
技术标签:
【中文标题】如何将 IN 运算符与 LIKE 条件相结合(或获得可比较结果的最佳方法)【英文标题】:How to combine IN operator with LIKE condition (or best way to get comparable results) 【发布时间】:2010-01-25 07:59:36 【问题描述】:我需要选择字段以几个不同前缀之一开头的行:
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 语句中给出所有前缀,或者将所有前缀存储在帮助表中。
前缀长度不固定。
【问题讨论】:
这些不同的前缀会改变吗? 可能有数百个前缀,但我希望看到在一个 SQL 子句中给出它们并将它们存储在帮助表中的选项 【参考方案1】:将前缀表与实际表连接起来可以在 SQL Server 和 Oracle 中使用。
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
【讨论】:
【参考方案2】:你可以试试regular expression
SELECT * from table where REGEXP_LIKE ( field, '^(ab|cd|ef)' );
【讨论】:
在 postgresql 中有没有办法做到这一点?【参考方案3】:如果你的前缀总是两个字符,你能不能不直接用 SUBSTRING() 函数获取“字段”的前两个字符,然后看看它是否在前缀列表中?
select * from table
where SUBSTRING(field, 1, 2) IN (prefix1, prefix2, prefix3...)
就简单性而言,这将是“最好的”,如果不是性能的话。性能方面,您可以创建一个索引虚拟列,从“字段”生成前缀,然后在谓词中使用虚拟列。
【讨论】:
谢谢!前缀不是固定长度。我编辑了问题。 啊,太糟糕了。我会留下我的答案,仅供有类似问题的人参考。【参考方案4】:根据数据集的大小,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);
【讨论】:
【参考方案5】:你也可以这样尝试,这里的 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
【讨论】:
以上是关于如何将 IN 运算符与 LIKE 条件相结合(或获得可比较结果的最佳方法)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MYSQL 查询中将“LIKE”与“IN”结合起来?
如何优化 Impala 查询以将 LIKE 与 IN 结合(字面意思或有效)?
BigQuery - 将正则表达式与 LIKE 运算符 (?) 结合使用