BETWEEN 行为不具有包容性

Posted

技术标签:

【中文标题】BETWEEN 行为不具有包容性【英文标题】:BETWEEN is not behaving in an inclusive manner 【发布时间】:2018-10-10 19:14:23 【问题描述】:

我有一个查询,它根据用户 ID 和两个日期从表中返回数据。日期看起来都是这样的: 2018-10-07T00:00:00.000Z 2018-10-06T00:00:00.000Z ...等等。

大多数情况下,查询会提供日期范围,如下所示:

SELECT * FROM "some_table" WHERE (user_id = 3 AND TIMESTAMP BETWEEN '2018-10-01' AND '2018-10-05') ORDER BY TIMESTAMP DESC

但有时用户可能会指定一天,在这种情况下,查询将如下所示:

SELECT * FROM "some_table" WHERE (user_id = 3 AND TIMESTAMP BETWEEN '2018-10-05' AND '2018-10-05') ORDER BY TIMESTAMP DESC

据我了解,BETWEEN 应该是包容性的……谁能帮我理解为什么它没有返回数据?

【问题讨论】:

包含,但您的日期范围从20181005 00:00:00.0020181005 00:00:00.00...soooo 它将正确包含所有时间戳 = 2018-10-05 00:00:00.0000000000000000 但其后 1 纳秒的记录。 假设您只检查日期而不是日期时间,您可以将 TIMESTAMP 转换为日期并将其用于比较 -- TIMESTAMP::date BETWEEN '2018-10-05' AND '2018-10 -05' 2018-10-06T00:00:00.000 不是“日期” - 它是时间戳,因此 时间 是比较的一部分。 【参考方案1】:

时间戳'2018-10-05'被理解为2018-10-05T00:00:00.000Z,所以你的范围是从2018-10-05T00:00:00.000Z2018-10-05T00:00:00.000Z,只有一毫秒。在查询中包含小时、分钟和秒,或者当开始日期和结束日期是同一天时,将结束日期增加一天。

为了更可靠地避免该问题,您可以考虑完全不使用带有日期的BETWEEN。请改用TIMESTAMP >= '2018-10-05' AND TIMESTAMP < '2018-10-06' 之类的东西。

【讨论】:

谢谢,没有意识到它会自动假设秒数。 BETWEEN 有时可能会很棘手,如果您像示例中那样在同一天进行操作,使用 <= and > 会有所帮助。 BETWEENDATE 值一点也不“棘手”。唯一“棘手”的地方是使用带有between 的时间戳 - 或者更糟糕的是,混合 时间戳和日期值。如果只有日期是相关的,也可以使用where "timestamp"::date between date '2018-10-01' and date '2018-10-05' @a_horse_with_no_name - 感谢您的提醒。在进行查询之前,我已将日期转换为时间戳。

以上是关于BETWEEN 行为不具有包容性的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL BETWEEN 运算符的行为不同

MySQL:索引具有多个 BETWEEN 表达式的 WHERE 子句

BETWEEN 具有相等限制的 SQL 查询

MS SQL Server“之间”是不是包括范围边界?

SQL:基于另一个表设置条件值,具有 BETWEEN 日期条件

HQL 中的 between 是不是严格比较?