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.00
到20181005 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.000Z
到2018-10-05T00:00:00.000Z
,只有一毫秒。在查询中包含小时、分钟和秒,或者当开始日期和结束日期是同一天时,将结束日期增加一天。
为了更可靠地避免该问题,您可以考虑完全不使用带有日期的BETWEEN
。请改用TIMESTAMP >= '2018-10-05' AND TIMESTAMP < '2018-10-06'
之类的东西。
【讨论】:
谢谢,没有意识到它会自动假设秒数。BETWEEN
有时可能会很棘手,如果您像示例中那样在同一天进行操作,使用 <= and >
会有所帮助。
BETWEEN
和 DATE
值一点也不“棘手”。唯一“棘手”的地方是使用带有between
的时间戳 - 或者更糟糕的是,混合 时间戳和日期值。如果只有日期是相关的,也可以使用where "timestamp"::date between date '2018-10-01' and date '2018-10-05'
@a_horse_with_no_name - 感谢您的提醒。在进行查询之前,我已将日期转换为时间戳。以上是关于BETWEEN 行为不具有包容性的主要内容,如果未能解决你的问题,请参考以下文章
MySQL:索引具有多个 BETWEEN 表达式的 WHERE 子句