PostgreSQL通配符LIKE,表示任意单词列表


156

我有一个约25个单词的简单清单。我在PostgreSQL中有一个varchar字段,假设该列表为['foo', 'bar', 'baz']。我想在表中找到任何包含这些单词的行。这会起作用,但是我想要更优雅的东西。

select *
from table
where (lower(value) like '%foo%' or lower(value) like '%bar%' or lower(value) like '%baz%')

Answers:


165

您可以使用SIMILAR TO支持交替的Postgres 运算符,即

select * from table where lower(value) similar to '%(foo|bar|baz)%';

1
正则表达式可能会加快速度:dba.stackexchange.com/questions/10694/…–

你怎么知道 ?我读过的大多数文档都说正则表达式速度较慢,而且还
很像

5
dba.stackexchange.com/a/10696/27757 SIMILAR TO在内部转换为正则表达式搜索
前标记考恩

我认为使用lower()是无效的,因为它将首先将每个字符串转换为小写,这比不区分大小写的匹配要昂贵得多
gilad mayani

228

PostgreSQL还支持完整的POSIX正则表达式

select * from table where value ~* 'foo|bar|baz';

~*是不区分大小写的匹配,~是区分大小写的。

另一种选择是使用ANY

select * from table where value  like any (array['%foo%', '%bar%', '%baz%']);
select * from table where value ilike any (array['%foo%', '%bar%', '%baz%']);

您可以对产生布尔值的任何运算符使用ANY。我怀疑正则表达式选项会更快,但是ANY是可用于工具箱的有用工具。


有趣的是,尽管这两种方法都比@chmullig的解决方案(因此+1)更优雅,但至少检查3个选项时,它们在大型表上执行的速度明显慢(在我的情况下为9150万条记录)。使用这两种方法时,我看到的时间增加了大约2倍。知道为什么会这样吗?
sage88

@ sage88我不知道该怎么做,但Erwin Brandstetter可能会有所帮助,并添加三字母索引可能会有所帮助。
亩太短了

13

PostgreSQL中实际上有一个运算符:

SELECT *
FROM table
WHERE lower(value) ~~ ANY('{%foo%,%bar%,%baz%}');


因此可以ILIKE搭配使用任何与数组中的一样吗?如果不需要花哨的正则表达式,这看起来很干净。还是将其内部翻译为正则表达式?
mlt

@mlt这是一个很好的问题,阅读文档不会提供明确的答案。SIMILAR TO确实转换为正则表达式,~operator代表POSIX正则表达式,但是对于尚不清楚LIKE
jlandercy '19

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.