我试图获取类型为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
子句中使用,是否有任何解决方案?
答案 0 :(得分:5)
我的question被标记为重复,并通过粗心的mod链接到一个脱离上下文的问题。这个问题与我的问题最接近,所以我在这里留下答案。 (我认为这可能会帮助那些unnest()
成为解决方案的人
在我的情况下,DISTINCT
和unnest()
的组合是解决方案:
SELECT DISTINCT ON (id_) *
FROM (
SELECT unnest(tags) tag, *
FROM someTable
) x
WHERE (tag like '%someInput%');
unnest(tags)
将文本数组扩展为行列表,DISTINCT ON (id_)
根据唯一的id_
列删除扩展产生的重复项。
<强>更新强>
在DISTINCT
子句中没有WHERE
的情况下执行此操作的另一种方法是:
SELECT *
FROM someTable
WHERE (
0 < (
SELECT COUNT(*)
FROM unnest(tags) AS tag
WHERE tag LIKE '%someInput%'
)
);
答案 1 :(得分:3)
了解ANY
不是运算符,但只能用于权限的SQL结构也很重要>一个运营商。更多:
LIKE
运算符 - 或者更准确地说:表达式,在内部的Postgres中被~~
运算符重写 - 期望<左边是em> value ,右边是 pattern 。这个运算符没有COMMUTATOR
(就像简单的等式运算符=
一样)所以Postgres不能翻转操作数。
您的尝试:
select * from someTable where '%someInput%' LIKE ANY(someColum);
已经翻转了左右操作数,因此'%someInput%'
是值,数组列someColum
的元素被视为模式(这不是你想要的)。
它 必须 ANY(someColum) LIKE '%someInput%'
- 除了ANY
构造不可能只允许权利运营商。你在这里遇到障碍。
相关:
unnest()
是您已经找到的解决方案 - 或者首先保存元素而不是数组(规范化架构)。
答案 2 :(得分:0)
一种公认的不完美的可能性可能是使用ARRAY_TO_STRING
,然后对结果使用LIKE
。例如:
SELECT *
FROM someTable
WHERE ARRAY_TO_STRING(someColum, '||') LIKE '%someInput%';
这种方法可能存在问题 ,因为有人可以在发现连接字符序列时搜索两个数组元素。例如,如果用户输入{'Hi','Mom'}
代替||
,则与i||M
相关联的someInput
数组会返回结果。相反,期望可能是在这种情况下没有结果,因为Hi
和Mom
都不包含i||M
字符序列。
答案 3 :(得分:0)
这个答案正是我想要的。它还提供了一些有用的技巧(和示例),以防您需要更大的灵活性。
它基本上解释了 ANY(), @> 和 && 运算符。
“如果要搜索多个值,可以使用@>运算符”
“ @>表示包含该数组中的所有值。如果要搜索当前数组是否包含另一个数组中的任何值,则可以使用&&”