为何SQL查询>= '5/1/2018'且<= '5/1/2018'仅返回当日零点数据?
为什么日期查询带不带时间戳结果不一样?
嘿,这个问题太有代表性了!我干数据库相关工作快20年,也见过好多人踩这个坑,核心原因就是数据库对日期字符串的隐式转换规则在搞事情,咱们一步步拆解:
1. 第一个查询的问题
当你执行:
SELECT * FROM sometable WHERE createdate >= '5/1/2018' and createdate <= '5/1/2018'
数据库会自动把不带时间部分的字符串'5/1/2018'转换成当天的零点时刻,也就是2018-05-01 00:00:00.000(具体精度取决于你的字段类型,比如datetime还是datetime2)。
这时候你的查询条件实际等价于:
createdate >= '2018-05-01 00:00:00' AND createdate <= '2018-05-01 00:00:00'
自然只能匹配那些createdate刚好是零点的行——任何当天其他时间(比如2018-05-01 09:30:00)都会因为大于零点,不满足<=的条件,被过滤掉。
2. 第二个查询的差异
你没写完的那个查询应该是类似createdate <= '5/1/2018 23:59:59'吧?当你明确指定了时间部分,数据库就会用你给的完整时间戳去匹配,这时候条件就变成了:
createdate >= '2018-05-01 00:00:00' AND createdate <= '2018-05-01 23:59:59'
这样就能匹配当天从零点到23:59:59的所有行,结果自然和第一个查询不一样了。
不过这里要提个小坑:如果你的字段是高精度的时间类型(比如datetime2(3)),那2018-05-01 23:59:59.999这种行还是会被漏掉,因为它比23:59:59大。
3. 更安全的写法
我平时推荐用这种方式来查询某一天的所有数据,完全避开时间精度的问题:
SELECT * FROM sometable WHERE createdate >= '2018-05-01' AND createdate < '2018-05-02'
不管createdate的时间部分是多少,只要是5月1日的,都会满足>= 5/1且<5/2的条件,既简洁又不会漏数据。
内容的提问来源于stack exchange,提问作者Indy-Jones
相关产品推荐
相关产品推荐

