【问题标题】:BETWEEN is not behaving in an inclusive mannerBETWEEN 行为不具有包容性
【发布时间】: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 不是“日期” - 它是时间戳,因此 时间 是比较的一部分。

标签: sql postgresql between


【解决方案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 - 感谢您的提醒。在进行查询之前,我已将日期转换为时间戳。
猜你喜欢
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多