SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


DATETIME Puzzle


DATETIME Puzzle

Author
Message
Hugo Kornelis
Hugo Kornelis
SSChampion
SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)

Group: General Forum Members
Points: 11050 Visits: 11998
Ola L Martins-329921 (11/17/2011)
GPO (11/17/2011)
There are good reasons to avoid using BETWEEN when comparing two datetimes. Particularly in the example the answer uses. You should be using the various symbols for GREATER THAN and LESS THAN.

No, I don't think you can (if not reverting to subqueries...)

The "AND" operator will check against the date-columns seperately - not simultaneously which in the case with "BETWEEN".
Using GREATER THAN and LESS THAN in the above question would actually return all the records.

(Sorry, being a bit rusty I'm not entirely sure this is correct, but I've been there, done that and bought the friggin' t-shirt...)

I'm afraid I don't understand you.
WHERE MyDate BETWEEN '20111101' AND '20111130' will not return everything for november - it will return everything for november 1 through 29, plus everything that happened at november 30, exactly midnight.
WHERE MyDate BETWEEN '20111101' AND '20111201' will also not return everything for november - it will return everything for november, plus everything that happened at december 1, exactly midnight.
The only correct code to return everything for november, nothing less, nothing more, is to use seperate >= and < tests:
WHERE MyDate >= '20111101' AND MyDate < '20111201'


Hugo Kornelis, SQL Server MVP
Visit my SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis
GilaMonster
GilaMonster
SSC Guru
SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)SSC Guru (87K reputation)

Group: General Forum Members
Points: 87881 Visits: 45274
Ola L Martins-329921 (11/17/2011)
The "AND" operator will check against the date-columns seperately - not simultaneously which in the case with "BETWEEN".
Using GREATER THAN and LESS THAN in the above question would actually return all the records.


BETWEEN is completely equivalent to a combination of <= and >=

SomeColumn BETWEEN @Var1 and @Var2 is exactly the same as SomeColumn >= @Var1 and SomeColumn <= @Var2. In fact, the SQL parser converts the BETWEEN into the <= and >= form during parsing (pre-execution)

Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

We walk in the dark places no others will enter
We stand on the bridge and no one may pass


SanDroid
SanDroid
SSCommitted
SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)SSCommitted (1.6K reputation)

Group: General Forum Members
Points: 1578 Visits: 1046
GPO (11/17/2011)
There are good reasons to avoid using BETWEEN when comparing two datetimes. Particularly in the example the answer uses. You should be using the various symbols for GREATER THAN and LESS THAN.


I wonder what your opinion is on INTERSECT, EXCEPT, or Common Table Expressions?

One BETWEEN statement easier to read than two or more GREATER THAN and LESS THAN statements.
SQLRNNR
SQLRNNR
SSC-Dedicated
SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)SSC-Dedicated (32K reputation)

Group: General Forum Members
Points: 32555 Visits: 18557
GilaMonster (11/17/2011)
Ola L Martins-329921 (11/17/2011)
The "AND" operator will check against the date-columns seperately - not simultaneously which in the case with "BETWEEN".
Using GREATER THAN and LESS THAN in the above question would actually return all the records.


BETWEEN is completely equivalent to a combination of <= and >=

SomeColumn BETWEEN @Var1 and @Var2 is exactly the same as SomeColumn >= @Var1 and SomeColumn <= @Var2. In fact, the SQL parser converts the BETWEEN into the <= and >= form during parsing (pre-execution)


I have seen this myth propagated from time to time (use lt and gt in lieu of between).



Jason AKA CirqueDeSQLeil
I have given a name to my pain...
MCM SQL Server, MVP


SQL RNNR

Posting Performance Based Questions - Gail Shaw

GPO
GPO
Ten Centuries
Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)

Group: General Forum Members
Points: 1307 Visits: 1929
If I were to write the query (which was )


SELECT *
FROM #DateTest
WHERE SampleDate BETWEEN @DATE1 AND @DATE2



I would have written it


SELECT *
FROM #DateTest
WHERE SampleDate >= @DATE1
AND SampleDate < (@DATE2 + 1)



That way I don't get into strife when my data contains a time that is greater than 23:59 and less than the start of the next day. Obviously I would have to remember to sanitise my inputs to ensure that the @date2 value coming in was a whole date (had no time fraction). Sorry I wasn't clearer earlier.

EDIT! EDIT! EDIT! I would have written it this way assuming of course that I wanted to return all the activity on @DATE2.

:-)

One of the symptoms of an approaching nervous breakdown is the belief that one's work is terribly important.
Bertrand Russell

GPO
GPO
Ten Centuries
Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)Ten Centuries (1.3K reputation)

Group: General Forum Members
Points: 1307 Visits: 1929
The only correct code to return everything for november, nothing less, nothing more, is to use seperate >= and < tests:
WHERE MyDate >= '20111101' AND MyDate < '20111201'


Massive thanks Hugo for putting this much more elegantly than I. Sorry to everyone elseBlush

:-)

One of the symptoms of an approaching nervous breakdown is the belief that one's work is terribly important.
Bertrand Russell

Ola L Martins-329921
Ola L Martins-329921
Old Hand
Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)Old Hand (350 reputation)

Group: General Forum Members
Points: 350 Visits: 188
Hugo Kornelis (11/17/2011)
Ola L Martins-329921 (11/17/2011)
GPO (11/17/2011)
There are good reasons to avoid using BETWEEN when comparing two datetimes. Particularly in the example the answer uses. You should be using the various symbols for GREATER THAN and LESS THAN.

No, I don't think you can (if not reverting to subqueries...)

The "AND" operator will check against the date-columns seperately - not simultaneously which in the case with "BETWEEN".
Using GREATER THAN and LESS THAN in the above question would actually return all the records.

(Sorry, being a bit rusty I'm not entirely sure this is correct, but I've been there, done that and bought the friggin' t-shirt...)

I'm afraid I don't understand you.
WHERE MyDate BETWEEN '20111101' AND '20111130' will not return everything for november - it will return everything for november 1 through 29, plus everything that happened at november 30, exactly midnight.
WHERE MyDate BETWEEN '20111101' AND '20111201' will also not return everything for november - it will return everything for november, plus everything that happened at december 1, exactly midnight.
The only correct code to return everything for november, nothing less, nothing more, is to use seperate >= and < tests:
WHERE MyDate >= '20111101' AND MyDate < '20111201'


2 × Blush
I confused this with another project I was working on a loooong time ago. No wonders I got it mixed up.
Thx Hugo for the explanation. And thx GilaMonster for explaining the parsing-part.
I will now crawl back under the stone where I came from... still blushing...
Hugo Kornelis
Hugo Kornelis
SSChampion
SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)SSChampion (11K reputation)

Group: General Forum Members
Points: 11050 Visits: 11998
GPO (11/17/2011)
I would have written it


SELECT *
FROM #DateTest
WHERE SampleDate >= @DATE1
AND SampleDate < (@DATE2 + 1)


That would have worked for the "old" date/time related data types (datetime and smalldatetime). But for the new date/time datatypes (datetime2, date, datetimeoffset), adding a day by using +1 is not supported. I suggest you switch to using DATEADD(day, 1, @DATE2) instead - that works for all date/tme datatypes, so your code won't break if you one day change to another data type.


Hugo Kornelis, SQL Server MVP
Visit my SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis
TomThomson
TomThomson
SSChampion
SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)

Group: General Forum Members
Points: 14358 Visits: 12204
Good question, which illustrates a point that has been known to trap inexperienced people and may help some of them for falling into the trap of thinking that when comparing a date and a datetime the date is implicitly converted to a date rather than the date being implicitly converted to a datetime.

But the description
I am extending Dwayne Dibley's question to show how 'Time' part in date is considered by SQL server

at the front of the question is a little inaccurate, albeit rather amusing. There is no 'Time' part in date, the issue being illustrated is actually what time part will be used in the result of an implicit conversion of a date (which has no time part) to datetime (which has to have one) [or for that matter to datetime2, or smalldatetime - all three datetime types have higher type precedence that date].

Tom

TomThomson
TomThomson
SSChampion
SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)SSChampion (14K reputation)

Group: General Forum Members
Points: 14358 Visits: 12204
Thomas Abraham (11/17/2011)
After Che Guevara's question from yesterday, I'll take the easy two points.

Drat! I'll have to change my avatar to something less recognisable! Crying Either that or change my nickname to "El comandante" so that it matches the avatar. w00t

Edit: I changed it. Still unmatched, though.

Tom

Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search