我想确定在PostgreSQL查询中是否可以将SIMILAR TO
与ANY
或ALL
结合使用。
它适用于LIKE
,即我可以做到:
SELECT 'man bear pig' LIKE ANY(ARRAY['%fish%', '%bear%']);
使用SIMILAR TO
尝试相同的操作:
SELECT 'man bear pig' SIMILAR TO ANY(ARRAY['%fish%', '%bear%']);
,它返回错误:
[42601] ERROR: syntax error at or near "ANY"
Position: 34
在这种情况下,它并没有太大的区别,但是请说我想使用扩展语法,例如%(man|pig)%
,然后LIKE
将返回与SIMILAR TO
不同的结果。
谢谢。
答案 0 :(得分:2)
您不能直接执行它,但是可以像PostgreSQL一样进行转换:
SELECT 'man bear pig'
~ ANY (ARRAY[
similar_escape('%fish%', NULL),
similar_escape('%bear%', NULL)
]);
但是直接使用正则表达式会更简单:
SELECT 'man bear pig'
~ ANY (ARRAY['fish', 'bear']);
答案 1 :(得分:1)
类似TO是有点奇怪的生物。它没有映射到的普通运算符(“ LIKE”映射到“ ~~”的方式),这可能就是为什么它不起作用的原因。相反,它似乎更像是一个宏,可以根据POSIX正则表达式进行重写。
explain SELECT * from pgbench_accounts where filler similar to '%(fish|bear)%';
QUERY PLAN
------------------------------------------------------------------------------------
Gather (cost=1000.00..45517.52 rows=1 width=97)
Workers Planned: 2
-> Parallel Seq Scan on pgbench_accounts (cost=0.00..44517.42 rows=1 width=97)
Filter: (filler ~ '^(?:.*(?:fish|bear).*)$'::text)
看看过滤器说它如何使用“〜”,并且字符串本身已被修改?
因此,一个答案是首先使用POSIX正则表达式,而不是SIMILAR TO。如果您不喜欢,则可以创建自己的运算符:
create function similar_to(text, text) returns bool language SQL as $$ select $1 similar to $2 $$;
create operator ~^~ (function = similar_to, leftarg=text, rightarg=text);
SELECT 'man bear pig' ~^~ ANY(ARRAY['%fish%', '%bear%']);
'〜^〜'这个名字是任意选择的,您可能想比我更认真地称呼它。
这可能不是最高效的处理方式,并且肯定会破坏任何可能会有用的索引(例如pg_trgm)。