PostgreSQL - text Array包含类似的值

时间:2016-01-07 14:30:23

标签: arrays postgresql sql-like any unnest

我试图获取类型为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子句中使用,是否有任何解决方案?

4 个答案:

答案 0 :(得分:5)

我的question被标记为重复,并通过粗心的mod链接到一个脱离上下文的问题。这个问题与我的问题最接近,所以我在这里留下答案。 (我认为这可能会帮助那些unnest()成为解决方案的人

在我的情况下,DISTINCTunnest()的组合是解决方案:

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数组会返回结果。相反,期望可能是在这种情况下没有结果,因为HiMom都不包含i||M字符序列。

答案 3 :(得分:0)

check this out

这个答案正是我想要的。它还提供了一些有用的技巧(和示例),以防您需要更大的灵活性。

它基本上解释了 ANY() @> && 运算符。

“如果要搜索多个值,可以使用@>运算符”

“ @>表示包含该数组中的所有值。如果要搜索当前数组是否包含另一个数组中的任何值,则可以使用&&”