如何在 Postgres 中对数组列使用 BETWEEN 条件?

Posted

技术标签:

【中文标题】如何在 Postgres 中对数组列使用 BETWEEN 条件?【英文标题】:How to use BETWEEN condition for array column in Postgres? 【发布时间】:2019-06-28 23:03:02 【问题描述】:

我在 Postgres 数据库中有一个 multiple_dates 列。 要找到一个特定的日期,我这样写:

SELECT * FROM companies
WHERE  '2019-06-30' = ANY (multiple_dates)

但我想使用 BETWEEN 子句按特定时间段进行搜索,如下所示:

SELECT * FROM companies
WHERE  (ANY (multiple_dates) BETWEEN '2019-06-01' AND '2019-06-30')  -- pseudo-code

此 SQL 不起作用。如何同时使用ANYBETWEEN 子句?

【问题讨论】:

【参考方案1】:

“问题”是ANY construct 适用于操作员,而不适用于其他构造 - 而BETWEEN 是另一个构造 .

相关:

Can IS DISTINCT FROM be combined with ANY or ALL somehow?

不过,有一个简单的解决方案。从给定的边界构造一个daterange 并使用contains operator @>

相关:

How to use the NOW() function as upper bound of a range?

那么查询可以是:

SELECT *
FROM   companies
WHERE  daterange('2019-06-01', '2019-06-30', '[]') @> ANY (multiple_dates)

注意第三个参数'[]' 以构造具有包含 边界的范围以匹配BETWEEN 的行为。


替代方案:标准化您的架构。创建一个 n:1 表,如:

CREATE TABLE company_date
   company_id  int NOT NULL REFERENCES companies
 , single_date date NOT NULL
 , PRIMARY KEY (company_id, single_date)
);

同时在(single_date, company_id) 上添加索引。见:

Is a composite index also good for queries on the first field?

那么你的查询可以是:

SELECT c.*
FROM   companies c
WHERE  EXISTS (
   SELECT FROM company_date cd
   WHERE  single_date BETWEEN '2019-06-01' AND '2019-06-30'
   AND    cd.company_id = c.company_id
   );

占用更多磁盘空间,查询更详细,但对于大表来说速度更快,用途更广泛。

【讨论】:

以上是关于如何在 Postgres 中对数组列使用 BETWEEN 条件?的主要内容,如果未能解决你的问题,请参考以下文章

使用Postgres和SQLAlchemy过滤数组列

使用 Postgres 和 SQLAlchemy 过滤数组列

如何在 postgres 中对 jsonb 值求和?

Postgres:如何获取多个布尔列的 json 数组?

如何在 Excel VBA 中对数组进行切片?

如何在 postgresql 中对 json 类型使用唯一约束