postgresql 检查Postgres数组中是否存在值

zpqajqem  于 2022-12-18  发布在  PostgreSQL
关注(0)|答案(7)|浏览(1290)

使用Postgres 9.0,我需要一种方法来测试一个给定数组中是否存在一个值。到目前为止,我得到了类似这样的结果:

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

但我一直在想应该有一个更简单的方法,我就是看不出来。这个看起来更好:

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

我相信这就足够了。但是如果你有其他的方法,请分享!

ymzxtsji

ymzxtsji1#

使用**ANY**构造时更简单:

SELECT value_variable = ANY ('{1,2,3}'::int[])

ANY的右操作数(在括号中)可以是set(例如,子查询的结果)或array。有几种方法可以使用它:

  • SQLAlchemy:如何过滤PgArray列类型?
  • PostgreSQL中的IN与ANY运算符
    重要差异:数组运算符(<@@>&&等)在PostgreSQL的标准分发中期望 array 类型作为操作数,期望support GIN or GiST indices,而ANY构造期望 element 类型作为左操作数,并且可以通过普通B树索引来支持(索引表达式位于运算符的 * 左侧 *,而不是像示例中那样相反)。示例:
  • 用于在JSON数组中查找元素的索引

这些都不适用于NULL元素。

  • 检查Postgres数组中是否存在NULL
l0oc07j2

l0oc07j22#

小心我掉进的陷阱:当检查某个值是否不存在于数组中时,不应执行以下操作:

SELECT value_variable != ANY('{1,2,3}'::int[])

而是使用了

SELECT value_variable != ALL('{1,2,3}'::int[])

而不是。

mwecs4sa

mwecs4sa3#

但是如果你有其他的方法,请分享。
你可以比较两个数组,如果左边数组中的值和右边数组中的值重叠,那么它返回true,这有点像黑客,但是它是有效的。

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • 在第一个和第二个查询中,值1位于右侧数组中
  • 请注意,第二个查询是true,尽管值4未包含在右侧数组中
  • 对于第三个查询,左数组中没有值(即4),右数组中没有值,因此它返回false
w1jd8yoj

w1jd8yoj4#

也可以使用**unnest**,它将数组扩展为一组行,然后简单地检查一个值是否存在,就像使用INNOT IN一样简单。
例如,在
1.标识符=〉通用标识符
1.异常列表标识=〉uuid[]
select * from table where id NOT IN (select unnest(exception_list_ids) from table2)

2ul0zpep

2ul0zpep5#

嗨,那个对我来说很好用,也许对某人有用

select * from your_table where array_column ::text ilike ANY (ARRAY['%text_to_search%'::text]);
camsedfj

camsedfj6#

“Any”很好用。只要确保any关键字在等号的右边,即出现在等号之后。
以下语句将引发错误:错误:“any”或其附近有语法错误

select 1 where any('{hello}'::text[]) = 'hello';

而下面的示例工作正常

select 1 where 'hello' = any('{hello}'::text[]);
plupiseo

plupiseo7#

当查找数组中是否存在某个元素时,需要进行正确的转换才能通过postgres的SQL解析器。下面是一个在join子句中使用数组包含操作符的示例查询:
为简单起见,我只列出相关部分:

table1 other_name text[]; -- is an array of text

所示SQL的连接部分

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

下面的方法也有效

on t2.panel = ANY(t1.other_name)


我只是猜测需要额外的强制转换,因为解析不必获取表定义来计算列的确切类型。

相关问题