如果我使用between
子句运行查询,则似乎排除了结束值
例如:
select * from person where dob between '2011-01-01' and '2011-01-31'
这会从{2011-01-01'到'2011-01-30'获得dob
的所有结果;跳过dob
为'2011-01-31'的记录。任何人都可以解释为什么这个查询的行为方式,以及如何修改它以包含dob
为'2011-01-31'的记录? (不会在结束日期加1,因为它已被用户选中。)
答案 0 :(得分:279)
来自MySQL-manual:
这相当于表达式 (min< = expr AND expr< = max)
答案 1 :(得分:162)
字段dob
可能包含时间组件。
将其截断:
select * from person
where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'
答案 2 :(得分:88)
问题是2011-01-31真的是2011-01-31 00:00:00。那是一天的开始。白天的一切都不包括在内。
答案 3 :(得分:28)
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'
答案 4 :(得分:6)
您在查询中引用的字段是日期类型还是日期时间类型?
您描述的行为的一个常见原因是当您使用DateTime类型时,您应该使用Date类型。也就是说,除非你真的需要知道某人出生的时间,否则只需使用日期类型。
结果中未包含最后一天的原因是查询假定您未在查询中指定的日期的时间部分的方式。
即:您的查询被解释为2011-01-30和2011-01-31之间的午夜,但数据可能在2011-01-31的当天晚些时候有一个值。
建议:如果字段是DateTime类型,请将字段更改为日期类型。
答案 5 :(得分:4)
这个查询对我有用,
select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
答案 6 :(得分:2)
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'
令人惊讶的是,这种转换是MySQL中许多问题的解决方案。
答案 7 :(得分:0)
将上限日期设置为日期+ 1天,因此在您的情况下,请将其设置为2011-02-01。
答案 8 :(得分: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
字段中的索引)一)。如果您进行类似using index condition
或using where
的操作,执行计划可能会从DATE(dob)
变为CAST(dob AS DATE)
,所以要小心!
答案 9 :(得分:0)
在MySql中,值之间包括所有值,因此当您尝试在“ 2011-01-01”和“ 2011-01-31”之间进行获取时
它将包括从2011-01-01 00:00:00
到2011-01-31 00:00:00
因此,自2011年1月31日以来,实际上该时间应该不算是2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
对于上限,您可以更改为2011-02-01
,然后它将获取所有数据,直到2011-01-31 23:59:59