查找文本数组包含类似于输入值的行

Jos*_*igo 6 arrays postgresql any sql-like unnest

我正在尝试获取类型列text[]包含类似于某些用户输入的值的行。

到目前为止,我一直在想和做的是使用'ANY'and 'LIKE'运算符,如下所示:

select * from someTable where '%someInput%' LIKE ANY(someColum);
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。该查询返回与此查询相同的值:

select * from someTable where 'someInput' = ANY(someColum);
Run Code Online (Sandbox Code Playgroud)

使用unnest()子查询中的函数我得到了很好的结果,但是WHERE如果可能,我需要查询此in 子句。

为什么LIKE操作员不与操作员一起工作,ANY并且我没有出现任何错误?我认为原因之一应该是ANY运算符在查询的右边,但是...

unnest()如果不使用WHERE条款,是否有解决方案?

Erw*_*ter 14

同样重要的是要明白,ANY不是运营商,但只能使用到的SQL构造正确的操作者。更多的:

LIKE操作员-或更准确地说:表达,即改写到~~ 操作者在内部的Postgres -预计向左和图案到右侧。COMMUTATOR这个运算符没有(就像简单的相等运算符一样=),所以 Postgres 不能翻转操作数。

你的尝试:

select * from someTable where '%someInput%' LIKE ANY(someColum);
Run Code Online (Sandbox Code Playgroud)

已翻转左右操作数,因此数组列'%someInput%'和元素someColum被视为模式(这不是您想要的)。

必须是ANY(someColum) LIKE '%someInput%'-除了这是不可能的ANY,其只允许构建正确的操作者。你在这里遇到了路障。

有关的:

您可以标准化您的关系设计并将数组元素保存在单独表中的单独行中。除此之外,unnest()就是解决方案,因为您已经找到了自己。但是,虽然您只对至少一个匹配元素的存在感兴趣,但EXISTS子查询将是最有效的,同时避免结果中的重复 - Postgres 可以在找到第一个匹配项后立即停止搜索:

SELECT *
FROM   tbl
WHERE  EXISTS (
    SELECT -- can be empty 
    FROM   unnest(someColum) elem
    WHERE  elem LIKE '%someInput%'
  );
Run Code Online (Sandbox Code Playgroud)

您可能想转义someInput. 看:

小心否定 ( NOT LIKE ALL (...)) 何时NULL可以参与:


Rot*_*eti 7

我的问题被标记为重复,并通过粗心的mod链接到上下文之外的问题。这里的问题最接近我的要求,所以我在这里留下答案。(我认为这可能会对寻求unnest()解决方案的人有所帮助)

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

SELECT DISTINCT ON (id_) *
FROM (
  SELECT unnest(tags) tag, *
  FROM someTable
  ) x
WHERE (tag like '%someInput%');
Run Code Online (Sandbox Code Playgroud)

unnest(tags)DISTINCT ON (id_)根据唯一id_列,将文本数组扩展为行列表,并删除扩展产生的重复项。

更新资料

DISTINCT不在WHERE子句中执行此操作的另一种方法是:

SELECT *
FROM someTable 
WHERE (
  0 < (
    SELECT COUNT(*) 
    FROM unnest(tags) AS tag
    WHERE tag LIKE '%someInput%'
  )
);
Run Code Online (Sandbox Code Playgroud)


Gol*_*TSU 5

一个公认的不完美的可能性可能是使用ARRAY_TO_STRING,然后LIKE针对结果使用。例如:

SELECT *
FROM someTable
WHERE ARRAY_TO_STRING(someColum, '||') LIKE '%someInput%';
Run Code Online (Sandbox Code Playgroud)

但是,这种方法可能存在问题,因为如果有人发现连接字符序列,他们可能会搜索两个数组元素。例如,如果用户代替输入{'Hi','Mom'},则连接到的数组||将返回结果。相反,期望可能是在那种情况下不会有结果,因为既不包含也不单独包含字符序列。i||MsomeInputHiMomi||M