检查Postgres数组中是否存在值

我需要一种方法来testing给定数组中是否存在一个值。 到目前为止,我想出了这样的事情

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

但我一直在想,应该有一个更简单的方法,我只是不能看到它。

编辑:刚才意识到我可以做到这一点

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

这样好多了,我相信也足够了,但是如果你有其他的方法去做,请分享一下。

使用ANY构造更简单:

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

ANY的右操作数(括号之间)可以是一个集合(例如子查询的结果) 数组 。 有几种使用方法:

  • SQLAlchemy:如何过滤PgArray列types?

重要的区别: 数组运算符( <@@>等)期望数组types作为操作数,并支持 PostgreSQL的标准分布中的GIN或GiST索引 ,而ANY构造期望元素types为左操作数,并且不支持这些索引。 例:

  • 在JSON数组中查找元素的索引

这对NULL元素没有任何作用。 要testingNULL

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

注意我陷入的陷阱:当检查数组中是否存在某个值时,不应该这样做:

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

但使用

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

代替。

但如果你有其他的方式来做,请分享。

你可以比较两个数组。 如果左侧数组中的任何值与右侧数组中的值重叠,则返回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

unnest也可以使用。 它将数组扩展为一组行,然后简单地检查一个值是否存在与使用INNOT IN一样简单。

例如

  1. id => uuid

  2. exception_list_ids => uuid []

select * from table where id NOT IN (select unnest(exception_list_ids) from table2)

当在数组中查找元素的存在时,需要进行适当的转换来传递postgres的SQLparsing器。 下面是在join子句中使用array contains操作符的一个示例查询:

为了简单起见,我只列出相关部分:

 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) 

我只是猜测,额外的转换是必需的,因为parsing不需要获取表定义来确定列的确切types。 其他人请评论这一点。