我正在尝试获取行,其中 text[]
类型的列包含类似于某些用户输入的值。
到目前为止,我的想法和做法是像这样使用 'ANY'
和 'LIKE
' 运算符:
select * from someTable where '%someInput%' LIKE ANY(someColum);
但它不起作用。该查询返回与该查询相同的值:
select * from someTable where 'someInput' = ANY(someColum);
我在子查询中使用 unnest()
函数得到了很好的结果,但如果可能的话,我需要在 WHERE
子句中查询它。
为什么 LIKE
运算符不能与 ANY
运算符一起使用并且我没有收到任何错误?我认为一个原因应该是 ANY
运算符在查询的右侧,但是......
有没有不使用 unnest()
的解决方案,如果可以在 WHERE
子句中解决?
最佳答案
ANY
不是运算符,而是一种 SQL 结构,只能用于右边运算符(operator)。更多:
LIKE
运算符 - 或者更准确地说:关键字,重写为 ~~
运算符 在 Postgres 内部 - 期望 value 在左边,pattern 在右边。没有 COMMUTATOR
对于这个运算符(就像简单的相等运算符 =
一样)所以 Postgres 不能翻转操作数。
你的尝试:
select * from someTable where '%someInput%' LIKE ANY(someColum);
... 左右操作数倒转。 '%someInput%'
是值,数组列 someColum
的元素被视为模式,这不是您想要的。
它将必须像ANY (someColum) LIKE '%someInput%'
- 但是ANY
构造只允许在运算符的右边。您遇到了障碍。
相关:
- Is there a way to usefully index a text column containing regex patterns?
- Can PostgreSQL index array columns?
您可以规范化您的关系设计并将数组的元素保存在单独表中的单独行中。除此之外,unnest()
是解决方案,因为您已经找到了自己。但是,虽然您只对至少一个匹配元素的存在感兴趣,但 EXISTS
子查询将是最有效的并避免结果中的重复项。 Postgres 可以在找到第一个匹配项后立即停止搜索:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- SELECT list can be empty for this purpose
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
您可能想要转义 someInput
中的特殊字符。见:
小心可能涉及NULL
时的否定(NOT LIKE ALL (...)
):
关于arrays - 查找文本数组包含与输入相似的值的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34657669/