检查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
也可以使用。 它将数组扩展为一组行,然后简单地检查一个值是否存在与使用IN
或NOT IN
一样简单。
例如
-
id => uuid
-
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。 其他人请评论这一点。