February 16, 2009 at 11:34 pm
If we execute the query with given data
SELECT [InsertedOn]
FROM MyLogs
WHERE [InsertedOn] BETWEEN '20090131' AND '20090131 23:59:59:999'
The output is as follows...
2009-01-31 00:00:00.000
2009-01-31 00:01:01.000
2009-01-31 12:59:59.127
2009-01-31 00:01:01.000
2009-01-31 13:00:00.997
2009-01-31 00:01:01.127
2009-02-01 00:00:00.000
2009-01-31 00:01:01.000
2009-01-31 21:59:58.347
2009-01-31 23:59:59.997
2009-01-31 00:01:01.000
2009-01-31 21:59:58.347
2009-02-01 00:00:00.000
2009-01-31 00:01:01.000
2009-01-31 22:59:58.347
2009-01-31 09:01:30.347
2009-02-01 00:00:00.000
with the above result the answer for the given questions will contain the value 2009-02-01 00:00:00.000.....
will not contain the following value
2009-01-30 00:00:00.000
February 17, 2009 at 12:08 am
I have the same experience, no 2009-01-30 00:00:00:000 in the result set.
According to the explanation this is correct behaviour.
Nice excersise though, this was new to me.
Robbert
February 17, 2009 at 1:01 am
The correct answer is only ONE:
2009-02-01 00:00:00:000, 2009-01-31 00:01:01:000, 2009-01-31 21:59:58:347
I do not know why there was a multiple choise.
The author of QotD.
February 17, 2009 at 1:32 am
The answer is incorrect since 2009-01-30 00:00:00:000 will not be returned. But you are pointing out a very important issue of SQL Server, datetime values are rounded to increments of .000, .003, or .007 seconds even in insert/update statements.
If you execute SELECT InsertedOn FROM MyLogs
you will see will see that '2009-01-31 23:59:59:999' are converted to '2009-02-01 00:00:00:000' when they were inserted.
If you use SQL Server 2008, there is a new datatype datetime2 with a precision of 100 nanoseconds. And if you try the same sample with datetime2 datatype you will end up with the correct result. But in the meantime, my recommendation is to not use BETWEEN in SQL Server 2005 for datetime values because of this side effects.
HΓ₯kan Winther
Senior development DBA
/HΓ₯kan Winther
MCITP:Database Developer 2008
MCTS: SQL Server 2008, Implementation and Maintenance
MCSE: Data Platform
February 17, 2009 at 1:48 am
I both liked and disliked this question.
The reason I like it, is that it points out a very common misconception when querying for intervals - I have lost track of how often I have seen people try to query for a one-day interval using some variation of the code in this question, instead of the correct way as demonstrated in the answer.
The reasons for not liking it are less significant, but there are more so they add up.
1) The way the answers were presented made it very hard to see exactly what they were. Each answer had two or three datetimes, often not in chronological order - the numbers started dancing before my eyes and I almost missed that one of the answers had a day number 30 instead of 31. I think it would have been easier to present one datetime value per answer options, arranged chronologically. After all, the QotD is about testing SQL Server skills, not skills in reading lots on similar looking numbers...
2) The "correct" answer lists four datetime values. There is no direct correspondence to any of the given answer options. I guess that the "correct" answer is the UNION of two or more of the given options, but after staring at these numbers to choose my answer, I frankly couldn't be bothered to repeat the exercise.
3) The "correct" answer is not correct at all. There is no way that 2009-01-30 00:00:00.000 can ever be returned by this query.
4) I saw only one answer that I thought to be completely correct. But the QotD permitted multiple answers, and when I submitted my own questions, I found no way to mark a question as "tick all that apply" without marking at least two answers as correct, so I assumed there had to be a second "correct" answer. The only one that wasn't obviously wrong was the first one, figuring that the author himself had accidentally missed that 2009-01-31 12:59:59:128 woukd be rounded to ~.127. All other answers were more wrong (in my eyes).
5) It's really a shame that the explanation in the answer focuses entirely on the ending numbers that can be returned (maybe that made Steve think the answer including Jan 30 should have been marked as correct as well?). A very important point here, maybe more important than the possible ending number, is that the datetime used in the query will also be rounded to one of those ending numbers - and in this case, the rounding will be UP, not down (rounding to the nearest value), so that feb 1st, midnight exactly, will be included in the results. This is what has taken many people br surprise, and should in my eyes have been the biggest takeaway of this question. Not whether SQL Server can return a datetime with a time part of 12:37:53.128.
6) Technically, all answers were wrong. SQL Server uses a period to seperate milliseconds from seconds, not a colon as shown in the answers.
All in all, I applaud the author for the idea of writing a QotD about the way datetimes are rounded and how a filter for a time interval should or shouldn't be constructed, but I am very disappointed that the many small errors made this a missed opportunity.
February 17, 2009 at 1:49 am
I think that the correct answer is the answer that shows those dates:
2009-02-01 00:00:00:000, 2009-01-31 00:01:01:000, 2009-01-31 21:59:58:347
All the dates are in the time frame that was in the query and all of them have the correct numbers in the milliseconds part.
For some reason the answer that was said to be correct was
2009-01-30 00:00:00:000, 2009-01-31 00:01:01:127, 2009-02-01 00:00:00:000, 2009-01-31 00:01:01:000, 2009-01-31 21:59:58:347. This couldn't be the correct answer because the date 2009-01-30 00:00:00:000 is not in the criteria that was specified in the query.
Adi
--------------------------------------------------------------
To know how to ask questions and increase the chances of getting asnwers:
http://www.sqlservercentral.com/articles/Best+Practices/61537/
For better answers on performance questions, click on the following...
http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
February 17, 2009 at 1:56 am
ok, so based on the question editor's comment above, this QOTD is broken - I answered the only one that contained only valid values (the one starting with "2009-02-01 00:00:00:000"), and got it "wrong".
I am happy to have learned something though - I did not know that DateTime milliseconds always ended in 0, 3 or 7; I knew there was rounding to the order of 3 milliseconds or so, but I did not know it was always consistently at those marks.
Thanks for an extra tidbit!
http://poorsql.com for T-SQL formatting: free as in speech, free as in beer, free to run in SSMS or on your version control server - free however you want it.
February 17, 2009 at 2:54 am
The principle of the question was good just the layout was poor as mentioned above and the answer given is obviously wrong - surprise that one person actually got this right. How about having a question like this what numbers am I thinking of 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 - We'd have as much chance of getting it correct π BTW I was thinking of 359 any other answers were wrong π
February 17, 2009 at 3:47 am
So .. do we get a bonus point because the QotD author got it wrong?
Oh, I just did by posting!
February 17, 2009 at 4:01 am
That gets my vote !
I've got two π
February 17, 2009 at 4:11 am
As one of the ones who got it "wrong" with the right answer, then I'm posting this just to claim my point too π
February 17, 2009 at 5:59 am
I didn't know that SQL Server rounded datetime...this is confusing behavior because I wouldn't have expected to see the '20090201' date in the result set. Try explaining that one to your business users.
If it was easy, everybody would be doing it!;)
February 17, 2009 at 6:12 am
Given that SQL is logic based, its a shame that the result was so ambiguous...
Like most, I got it wrong too however given the explanation, surely the data capture is between:
2009-01-30 23:59:59.007 AND 2009-01-31 23:59:59.007
and therefore option 'C' is the only correct selection.
Glen Parker π
February 17, 2009 at 6:16 am
Glen Parker (2/17/2009)
Given that SQL is logic based, its a shame that the result was so ambiguous...Like most, I got it wrong too however given the explanation, surely the data capture is between:
2009-01-30 23:59:59.007 AND 2009-01-31 23:59:59.007
and therefore option 'C' is the only correct selection.
Hi Glen,
No, that's not correct. The upper limit in the BETWEEN proposition (2009-01-31 23:59:59.999) has to be converted to a proper datetime value. It can either be rounded down (to 2009-01-31 23:59:99.997), or up (to 2009-02-01 0:00:00.000). The rounding will go to the nearest value that can be represented, so in this case the rounding will be up. After the conversion, the query will work as if it was stated as "... BETWEEN ... AND 2009-02-01 0:00:00.000, and hence the latter datetime value will be returned as well.
Viewing 15 posts - 1 through 15 (of 52 total)
You must be logged in to reply to this topic. Login to reply