PostgreSQL。按数组字段值的交集过滤

Posted

技术标签:

【中文标题】PostgreSQL。按数组字段值的交集过滤【英文标题】:postgresql. filter by intersection of array field values 【发布时间】:2016-09-30 14:59:58 【问题描述】:

我的数据集是:

# select * from test;
   list   | locked
 ---------+--------
  a,b,c | t
  f,g,h | f
  c,d,e | f

我需要选择列表值不与任何locked=TRUE 行相交的locked=FALSE 行。

到现在为止,我被困住了:

# SELECT * FROM test WHERE NOT locked and NOT list && (SELECT list FROM test WHERE locked);
  list   | locked
---------+--------
 f,g,h | f
 (1 row)

工作,但通过比较每个locked=TRUE 行看起来开销很大。我正在寻找一种方法来选择所有locked=TRUE 列表值的聚合集,并对每个locked=FALSE 行进行一次比较。

【问题讨论】:

【参考方案1】:

您的查询应该可以正常工作。如果我对您的理解正确,那么您正在寻找更有效的东西。如果你愿意创建一个新表,你可以这样:

CREATE TABLE locked(elem text PRIMARY KEY);
INSERT INTO locked SELECT DISTINCT unnest(list) FROM test WHERE locked;

此表将包含来自test 的所有列表中与锁定状态相对应的所有元素。我正在使用unnest 函数将(看起来是)text[] 转换为text 的表,以便我可以应用DISTINCT

那么你会像这样使用那个表

SELECT *
FROM test
WHERE NOT locked AND
      NOT exists(SELECT FROM locked WHERE elem=ANY (list));

请注意,最后一个查询中的NOT locked 条件是多余的,但如果使用它可能会提高性能。

如果您需要更好的性能,您可能需要进一步规范化表test

【讨论】:

这是个好建议。但 ti 不满足我的需求。锁机制意味着并发。我的表应该作为作业队列工作,其中并发工作者通过设置锁定属性和 RETURNING * 的 UPDATE 行获取作业,因此其他工作者不能接受它。在这种情况下,管理单独的锁表比比较每一行的开销要大得多。

以上是关于PostgreSQL。按数组字段值的交集过滤的主要内容,如果未能解决你的问题,请参考以下文章

按字段名称在新的 JS 过滤数组中移动 JS 数组行

Django Queryset 按确切字符串过滤数组字段

PostgreSQL 连接性能

SQLAlchemy:如何按两个字段分组并按日期过滤

尝试使用过滤器设置具有唯一值的数组失败

是否可以通过检查它们的交集是否为空来过滤 django 多对多 QuerySet 字段?