简体   繁体   English

我的SQL中存在日期和日期时间比较问题

[英]Having a Date And DateTime Comparison problem in my SQL

Been testing this over and over, and it fails at the date comparison.( item.id_type seems to work fine). 一遍又一遍地测试,结果在日期比较时失败了。( item.id_type似乎工作正常)。

request.date has the datatype DATETIME . request.date的数据类型为DATETIME

SELECT request.id, request.date, request.total_price,
    item.cod_GERFIP,item.price,item.name,request_item.quantity,
    section.name AS section,user.firstname,user.lastname   

FROM ((((`request_item` 
INNER JOIN `request` ON  request_item.id_request = request.id)
INNER JOIN `item` ON request_item.id_item = item.cod_GERFIP)
INNER JOIN `user` ON request.id_user = user.id) 
INNER JOIN `section` ON user.section = section.id) 

WHERE request.date >= '2019-01-09' AND request.date <= '2019-01-10'  
    AND item.id_type = '1' 
ORDER BY request.date DESC

Just a guess, because you haven't explained what or how the query fails, but to my eyes this condition does not look correct: 只是一个猜测,因为您还没有解释查询失败的方式或方式,但是在我看来,这种情况看起来并不正确:

 request.date <= '2019-01-10' 

It's a common mistake to expect a condition like this, when used a part of a range, to include all records where the date part of a datetime field is 2019-01-10 . 当使用这样的条件作为范围的一部分时,期望这样的条件包含datetime字段的date部分为2019-01-10所有记录是一个常见错误。 That is, if we have an example value in the database of 1 PM on the same day ( 2019-01-10 13:00:00 ), the expectation is this value will narrow to match the 2019-01-10 literal in the query, the two values will be equal, and so it will meet the condition. 也就是说,如果我们在同一天( 2019-01-10 13:00:00 )的下午1点的数据库中有一个示例值,则期望该值将缩小以匹配表中的2019-01-10文字。查询时,两个值将相等,因此将满足条件。

It does work this way. 它确实以这种方式工作。

Instead, the 2019-01-10 literal in the query is widened to a full DateTime, that looks more like this: 2019-01-10 00:00:00.000 . 而是将查询中的2019-01-10文字扩展为完整的DateTime,看起来像这样: 2019-01-10 00:00:00.000 Now the 1 PM value from the table is compared with this full date time, and it fails the condition. 现在,将表中的1 PM值与此完整的日期时间进行比较,并且该条件失败。

It's much more common for a date range to compare using an exclusive upper bound set for one day in the future: 对于日期范围,更常见的是使用将来一天的专有上限进行比较:

request.date < '2019-01-11'

Alternatively, you may be tempted to do this: 或者,您可能会想这样做:

request.date <= '2019-01-10 23:59:59.999'

It will even work most of the time. 它甚至在大多数时间都可以工作。 Just be warned that in the (rare) case of leap seconds, you can still end up with incorrect results that way. 请注意,在(很少)of秒的情况下,您仍然可能以这种方式得到错误的结果。

You may also be tempted to do something like this: 您可能也很想做这样的事情:

convert(date,request.date) <= '2019-01-10'

This works, but it's not recommended because it prevents the use of any index you might have on the request.date field, and that cuts at the core of database performance. 这行得通,但是不建议这样做,因为它会阻止使用您可能在request.date字段上使用的任何索引,并且这降低了数据库性能的核心。


Or maybe the problem is even simpler. 也许问题甚至更简单。 With the start of range at 2019-01-09 , maybe you wanted to get the records for exactly one day, and are surprised to see a few values from midnight on 2010-01-10 . 随着范围的开始于2019-01-09 ,也许您想获取准确的一天的记录,并且很惊讶地看到2010-01-10午夜的一些值。 Again, the solution is you want an exclusive boundary at the top of the range: 同样,解决方案是您要在范围的顶部使用排他边界:

request.date < '2019-01-10'

As a complete side note to the question, I'm a very sad the SQL BETWEEN operator is inclusive at both end of the range. 作为对该问题的完整说明,我很遗憾SQL BETWEEN运算符在范围的两端都包含在内。 This may make sense for numeric or string data, but for date values defining an exclusive upper bound for the BETWEEN operator would have made much more sense. 这对于数字或字符串数​​据可能是有意义的,但是对于为BETWEEN运算符定义排他上限的日期值,它会更有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM