将字符串模式与任何数组元素匹配

Mar*_*lom 3 postgresql

我正在尝试将字符串模式与数组中的任何字符串进行匹配:

SELECT 'abc' LIKE ANY('{"abc","def"}') -- TRUE

-- BUT

SELECT 'ab%' LIKE ANY('{"abc","def"}') -- FALSE, I expect TRUE
Run Code Online (Sandbox Code Playgroud)

第二个查询有什么问题?

jja*_*nes 7

如果 PostgreSQL 允许在左侧操作数上使用 ANY 就好了,但遗憾的是它不允许。所以你需要LIKE的换向器。PostgreSQL 没有附带一个,但您可以创建自己的。

您需要一个函数来反转 LIKE 参数的顺序,然后使用它创建一个可以与 ANY 结合使用的运算符。用户创建的运算符必须用符号命名,而不是文本,所以我选择“<~~”。'~~' 是 LIKE 的内置同义词,因此我添加 '<' 作为 pneumonic,使其“走另一条路”。不过,您可以选择任何您想要的未使用的名称。

create function reverse_like (text, text) returns boolean language sql as $$ select $2 like $1 $$;
create operator <~~ ( function =reverse_like, leftarg = text, rightarg=text );
SELECT 'ab%' <~~ ANY('{"abc","def"}');
Run Code Online (Sandbox Code Playgroud)

您可能应该将该函数标记为不可变,如果您使用的是 v9.6 或更高版本,也应该标记为并行安全。

create or replace function reverse_like (text, text) returns boolean language sql as
 $$ select $2 like $1 $$ immutable parallel safe;
Run Code Online (Sandbox Code Playgroud)