157

如果我使用between子句运行查询,它似乎排除了结束值。
例如:

select * from person where dob between '2011-01-01' and '2011-01-31'

这将获得dob从 '2011-01-01' 到 '2011-01-30' 的所有结果;跳过dob“2011-01-31”的记录。谁能解释为什么这个查询会这样,以及我如何修改它以包含dob“2011-01-31”的记录?(没有在结束日期上加 1,因为它是由用户选择的。)

4

11 回答 11

319

MySQL 手册

这等价于表达式 (min <= expr AND expr <= max)

于 2011-02-22T16:30:57.403 回答
199

该字段dob可能具有时间组件。

要截断它:

select * from person 
where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'
于 2011-02-22T16:40:17.183 回答
113

问题是 2011-01-31 真的是 2011-01-31 00:00:00。那是一天的开始。不包括白天的一切。

于 2011-02-22T16:35:13.513 回答
34
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'
于 2011-02-22T16:30:42.797 回答
8

您在查询中引用的字段是Date类型还是DateTime类型?

您描述的行为的一个常见原因是当您使用 DateTime 类型时,您确实应该使用 Date 类型。也就是说,除非您真的需要知道某人的出生时间,否则只需使用 Date 类型。

最后一天未包含在您的结果中的原因是查询假定您未在查询中指定的日期的时间部分的方式。

也就是说:您的查询被解释为截至 2011 年 1 月 30 日至 2011 年 1 月 31 日之间的午夜,但数据可能在 2011 年 1 月 31 日当天晚些时候的某个时间有一个值。

建议:如果是 DateTime 类型,则将字段更改为 Date 类型。

于 2011-02-22T16:34:59.517 回答
6

嗨,这个查询对我有用,

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
于 2013-12-09T23:18:09.350 回答
4
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'

令人惊讶的是,这种转换是 MySQL 中许多问题的解决方案。

于 2013-08-14T12:22:42.757 回答
1

在 MySql 之间的值是包容性的,因此当你尝试在 '2011-01-01' 和 '2011-01-31' 之间获取

它将包括从2011-01-01 00:00:00upto2011-01-31 00:00:00 因此实际上在 2011-01-31 中没有任何内容,因为它的时间应该从2011-01-31 00:00:00 ~ 2011-01-31 23:59:59

对于上限,您可以更改为,2011-02-01然后它将获取所有数据2011-01-31 23:59:59

于 2019-10-29T08:25:52.853 回答
0

将日期上限设置为 date + 1 天,因此在您的情况下,将其设置为 2011-02-01。

于 2011-02-22T16:26:52.520 回答
0

您可以将查询运行为:

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'

就像其他人指出的那样,如果您的日期是硬编码的。

另一方面,如果日期在另一个表中,您可以添加一天并减去一秒(如果保存的日期没有秒/时间),例如:

select * from person JOIN some_table ... where dob between some_table.initial_date and (some_table.final_date + INTERVAL 1 DAY - INTERVAL 1 SECOND)

避免对字段进行强制转换dob(如在接受的答案中),因为这会导致巨大的性能问题(例如无法在dob字段中使用索引,假设有一个)。如果你做类似or的东西,执行计划可能会从using index conditionto改变,所以要小心!using whereDATE(dob)CAST(dob AS DATE)

于 2019-01-04T17:37:36.553 回答
0
select * from person where dob between '2011-01-01' and '2011-01-31' or dob like' 2011-01-31%'

只需添加or <<column>> like "date%".

于 2022-02-20T16:28:29.633 回答