views:

10401

answers:

8
SELECT GETDATE()

Returns: 2008-09-22 15:24:13.790

I want that date part without the time part: 2008-09-22 00:00:00.000

A: 
SELECT CONVERT(VARCHAR(10),GETDATE(),111)
Nescio
This returns '2008/09/22' for me
eddiegroves
111 is the Japanese format. yyy/mm/dd
Ricardo C
A: 

SELECT CONVERT(datetime, CONVERT(varchar, GETDATE(), 101))

Cade Roux
+25  A: 
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))

for example

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))

gives me

2008-09-22 00:00:00.000

Pros:

  • No varchar<->datetime conversions required
  • No need to think about locale

EDIT:

Just wondering, why people keep downvoting my answer? Think it's incorrect? Prove it!

aku
Mine keeps getting downvoted, too. Odd.
Cade Roux
Is this way better or worse performance wise than using the convert methods other have suggested? Or is it negligible?
eddiegroves
My method works faster. It doesn't require conversions to varchar and allows efficient date calculations
aku
Cade Roux, sometimes stackoverflow looks like idiotsoverflow. people just downvote without having a tiny bit of understanding of how it works
aku
i think it's pretty poor etiquette to downvote without leaving a comment regarding why...
nickf
+1 Looks like this one is 35% faster than the double convert() method commonly used (which I also have used for years). Nice one.
Dane
If this is 35% than the CONVERT method, you've got to wonder how much faster a built-in truncate would be - this has to be the most common datetime-related operation I ever do - I'm going to see about switching to this mechanism.
Cade Roux
The only downside I can see to your solution is that unless you know what it is doing it is a bit obtuse. Using the double convert method makes your intentions more obvious to futire code maintainers. BTW I have not downvoted you. I think I'll start using your method too. Thankyou @aku
Jim Birchall
+1 You may be interested to see Ricardo C's edited answer (since it is community wiki and factually incorrect, I corrected it). You also got a prop to your question.
Emtucifor
Also don't miss [this post](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991) showing performance testing results.
Emtucifor
A: 

You can use the 'convert' function to return only the date. See the link below:

Date and Time Manipulation in SQL Server 2000

The syntax for using the convert function is:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

DaveK
+2  A: 
select dateadd(dd, datediff(dd, 0, getdate()), 0)

select dateadd(day, 0, datediff(day,0, getdate()))

select convert(datetime, convert(varchar(10), getdate(), 101))

Edit: The first two methods are essentially the same, and out perform the convert to varchar method.

Gordon Bell
These methods are all great, but which single one do you suggest using?
eddiegroves
+7  A: 

Using FLOOR() - just cut time part.

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
DiGi
This method is not the fastest, and also implicitly teaches people that casting dates to float is accurate, which it is not. Please see [this post](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991) for more detail.
Emtucifor
+8  A: 

DATEADD and DATEDIFF are better than CONVERTing to varchar. Both queries have the same execution plan, but execution plans are primarly about data access strategies and do not always reveal implicit costs involved in the CPU time taken to perform all the pieces. If both queries are run against a table with millions of rows, the CPU time using DateDiff can be close to 1/3rd of the Convert CPU time!

To see execution plans for queries:

set showplan_text on
GO 

Both DATEADD and DATEDIFF will execute a CONVERT_IMPLICIT.

Although the CONVERT solution is simpler and easier to read for some, it is slower. There is no need to cast back to datetime (this is implicitly done by the server). There is also no real need in the DateDiff method for DateAdd afterward as the integer result will also be implicitly converted back to datetime.


SELECT CONVERT(varchar, MyDate, 101) FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, MyDate)) FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

Using FLOOR() as @digi suggested has performance closer to DateDiff, but is not recommended as casting the datetime data type to float and back does not always yield the original value.

Remember guys: Don't believe anyone. Look at the performance statistics, and test it yourself!

Be careful when you're testing your results. Selecting many rows to the client will hide the performance difference becauses it takes longer to send the rows over the network than it does to perform the calculations. So make sure that the work for all the rows is done by the server but there is no rowset sent to the client.

There seems to be confusion for some people about when cache optimization affects queries. Running two queries in the same batch or in separate batches has no effect on caching. So you can either expire the cache manually or simply run the queries back and forth multiple times. Any optimization for query #2 would also affect any subsequent queries, so throw out execution #1 if you like.

Here is full test script and performance results that prove DateDiff is substantially faster than converting to varchar.

Ricardo C
Ricardo C, nice investigation! What version of SQL server do you use? On MSSQL2000 method with datediff performs slightly faster for me.
aku
Just to note, I performed test 1000.000 times. For real-world scenarios performance difference will not be noticeable, I guess
aku
Aku, I used SQL Server 2005 Express for this test. I work on 2000 at work, and I will test it with a table with over 24 million rows and see what comes out of it.
Ricardo C
Ricardo C, cool! I'm really interested how it will perform on real data base.
aku
Aku, same results. No difference in performance over ten million rows.
Ricardo C
Ricardo C, thanks for this investigation. I wish there will be more delving into every detail users like you.
aku
The claims about equal performance are not true. Of course the execution plans will be the same!!! Measuring performance on these MUST be done by comparing CPU usage, not examining execution plans.
Emtucifor
+3  A: 

SQLServer 2008 now has a Date datatype which contains only a date with no time. So for anyone using SQLServer 2008 you can do the following:

select CONVERT(date, getdate())
BenR