Thu 28 Aug 2008
Why not to use BETWEEN for DateTime comparisons in SQL Server 2007
Posted by Christian Donner under MiscellaneousThe issue with BETWEEN is that it does not behave consistenly. Sometimes it is inclusive of the 2nd DateTime value, sometimes it is not.
Consider the following:
select case when '9/1/08' between '9/1/08' and '9/15/08' then 'in' else 'out' end as s1, case when '9/1/08' between '8/28/08' and '9/1/08' then 'in' else 'out' end as s2 s1 s2 ---- ---- in in (1 row(s) affected)
select case when '1/1/08' between '1/1/08' and '2/1/08' then 'in' else 'out' end as s1, case when '1/1/08' between '12/31/07' and '1/1/08' then 'in' else 'out' end as s2 s1 s2 ---- ---- in out (1 row(s) affected
One would expect the same results for both queries. Since SQL Server internally adds a 00:00:00.000 timestamp to date constants without a time value, one could suspect that it does not do that in a consistent manner. However, explicitely adding time values to the dates does not change the results:
select case when '9/1/08 00:00:00.000' between '9/1/08 00:00:00.000' and '9/15/08 00:00:00.000' then 'in' else 'out' end as s1, case when '9/1/08 00:00:00.000' between '8/28/08 00:00:00.000' and '9/1/08 00:00:00.000' then 'in' else 'out' end as s2 s1 s2 ---- ---- in in (1 row(s) affected
select case when '1/1/08 00:00:00.000' between '1/1/08 00:00:00.000' and '2/1/08 00:00:00.000' then 'in' else 'out' end as s1, case when '1/1/08 00:00:00.000' between '12/31/07 00:00:00.000' and '1/1/08 00:00:00.000' then 'in' else 'out' end as s2 s1 s2 ---- ---- in out (1 row(s) affected
Use explicit comparison operators < ,>,< =, >= instead of BETWEEN to control whether a DateTime comparison is inclusive or not.
The reason for this appears to be that SQL Server’s internal resolution for DateTime is 3.33 ms (as explained by Steve Kozak in SQL Server Professional) - larger than the least significant digit.
