595

Which method provides the best performance when removing the time portion from a datetime field in SQL Server?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

or

b) select cast(convert(char(11), getdate(), 113) as datetime)

The second method does send a few more bytes either way but that might not be as important as the speed of the conversion.

Both also appear to be very fast, but there might be a difference in speed when dealing with hundreds-of-thousands or more rows?

Also, is it possible that there are even better methods to get rid of the time portion of a datetime in SQL?

gbn
  • 422,506
  • 82
  • 585
  • 676
Stephen Perelson
  • 6,613
  • 3
  • 21
  • 15
  • 1
    I've tried this out on one million records in one of my production tables and I couldn't get an accurate reading on performance either way. Both methods returned the exact same amount of data though. – Stephen Perelson Jul 24 '09 at 13:05
  • string manipulation is mcuh more CPU intensive. DATEADD and DATEDIFF are designed to make best use of the storage representation used by SQL Server. – MatBailie Jul 24 '09 at 13:22
  • 9
    On 18,000,000 rows this is what I've found (SQL Server 2008): Method b is about 24% slower than method a. CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME) is 3.5% slower than method a. Method a seems to be a winner with regards to performance. Thanks all for the great answers. – Stephen Perelson Jul 24 '09 at 13:33
  • 53
    Why the heck doesn't SQL have a built-in function to do this anyway?!! – Gary McGill Jul 24 '09 at 14:17
  • 12
    SQL 2008's new DATE datatype will handle this. – Philip Kelley Jul 24 '09 at 14:23
  • I tried CASTing the datetime to a date and it was even slower than method b. If you don't need to store the time portion then this datatype would work very well. – Stephen Perelson Jul 24 '09 at 15:33
  • 3
    possible duplicate of [Most efficient way in SQL Server to get date from date+time?](http://stackoverflow.com/questions/133081/most-efficient-way-in-sql-server-to-get-date-from-datetime) – Richard Szalay May 28 '10 at 09:51
  • Duplicate of [How to remove the time portion of a datetime value (SQL Server)?](http://stackoverflow.com/questions/2775/how-to-remove-the-time-portion-of-a-datetime-value-sql-server) – Yagzii Feb 16 '15 at 15:36

23 Answers23

626

Strictly, method a is the least resource intensive:

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

Proven less CPU intensive for the same total duration a million rows by someone with way too much time on their hands: Most efficient way in SQL Server to get a date from date+time?

I saw a similar test elsewhere with similar results too.

I prefer the DATEADD/DATEDIFF because:

Edit, Oct 2011

For SQL Server 2008+, you can CAST to date i.e. CAST(getdate() AS date). Or just use date datatype so no time to remove.

Edit, Jan 2012

A worked example of how flexible this is: Need to calculate by rounded time or date figure in sql server

Edit, May 2012

Do not use this in WHERE clauses and the like without thinking: adding a function or CAST to a column invalidates index usage. See number 2 here Common SQL Programming Mistakes

Now, this does have an example of later SQL Server optimiser versions managing CAST to date correctly, but generally it will be a bad idea ...

Edit, Sep 2018, for datetime2

DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2epoch datetime2 = '19000101'

select DATEADD(dd, DATEDIFF(dd, @datetime2epoch, @datetime2value), @datetime2epoch)
greybeard
  • 2,249
  • 8
  • 30
  • 66
gbn
  • 422,506
  • 82
  • 585
  • 676
  • 4
    @David Sopko for the Oct 2011 edit then code would be: select cast(GETDATE() as date) – Choco Smith Dec 15 '14 at 08:51
  • 1
    For more recent versions of SQL, using date instead of datetime avoids the need to deal with hours. Use the following sample: declare noTime date = getdate(), withTime datetime = getdate() select @noTime,@withTime – ozkary Jan 19 '17 at 23:28
  • 1
    the cast as date is great if you just need the date. However often you need the current date at midnight so you can then do some further date manipulation. the `DATE` data time is obnoxiously restrictive at what it will let you do with regard to things like dateadd, datediff and interacting with other date/time data types. For those cases, the `DATEADD()` approach reigns king. – Xedni Jul 11 '17 at 17:02
  • This does not work for every date. I had mistakenly entered `0218` instead of `2018` as the year and the `DATEDIFF` part of your statement throws an exception `The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range datetime value` Try: `select DATEDIFF(dd, 0, convert(datetime2(0), '0218-09-12', 120))` – Bernhard Döbler Sep 12 '18 at 16:03
  • 1
    @BernhardDöbler in Jul 2009 when I answered , "0218" would have been a valid date so you would not have got this far. Also the "0" does not convert to 19000101 for datetime2. Try this select `SELECT DATEDIFF(dd, '19000101', convert(datetime2(0), '0218-09-12', 120))` – gbn Sep 13 '18 at 09:34
  • Naming the variable `epoch` is confusing because it's not 1970, but 1900. 1900 is the minimum value that `DATEDIFF` uses, so it makes sense to keep using 1900. The variable should be renamed to something else. – Rudey Sep 22 '20 at 10:32
  • Where is 1970 mentioned? @Rudey – gbn Sep 22 '20 at 16:05
83

In SQL Server 2008, you can use:

CONVERT(DATE, getdate(), 101)
shA.t
  • 16,580
  • 5
  • 54
  • 111
Anto Raja Prakash
  • 1,328
  • 8
  • 12
  • 20
    The third argument has absolutely no bearing on the result when converting from a `datetime` to a `date`, and so your solution effectively boils down to just `CONVERT(DATE,getdate())`, which has already been suggested more than once. – Andriy M Oct 26 '13 at 19:46
  • 4
    Just use `CAST(GETDATE() AS DATE)` or strictly ANSI `CAST(CURRENT_TIMESTAMP AS DATE)` which I think is worthless. Stay with the first one. –  Sep 05 '18 at 21:10
66

Of-course this is an old thread but to make it complete.

From SQL 2008 you can use DATE datatype so you can simply do:

SELECT CONVERT(DATE,GETDATE())
shA.t
  • 16,580
  • 5
  • 54
  • 111
Arjan Fraaij
  • 661
  • 5
  • 2
29

In SQL Server 2008, there is a DATE datetype (also a TIME datatype).

CAST(GetDate() as DATE)

or

declare @Dt as DATE = GetDate()
Metaphor
  • 6,157
  • 10
  • 54
  • 77
  • This is what I used and it worked well. Seems like the simplest answer. Any downsides over using in conjunction w/ CONVERT? – joelmdev Jan 29 '18 at 18:16
  • 3
    CAST and CONVERT are equivalent in function. The difference is that CAST is part of the ANSI standard, while CONVERT is specific to T-SQL. So, use CAST wherever possible. – troy Sep 05 '18 at 18:40
  • 1
    @troy I use CAST because I can save 3 typing letters and syntax is clearer than CONVERT, the ANSI Standard part is worthless –  Sep 05 '18 at 21:13
19
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)

...is not a good solution, per the comments below.

I would delete this answer, but I'll leave it here as a counter-example since I think the commenters' explanation of why it's not a good idea is still useful.

Gary McGill
  • 26,400
  • 25
  • 118
  • 202
  • See GBN's answer, many have investigated this. DATETIMEs are NOT stored as floats, and so using DATEADD/DATEDIFF avoids the mathmatical manipulation need to CAST between types. – MatBailie Jul 24 '09 at 13:29
  • I can accept that you might want to avoid a cast from DATETIME to FLOAT for the reason you describe, but in that case isn't the implicit conversion from zero in the OPs option (a) also a problem? Hmmm... I suppose in that case it's not a FLOAT and that the server is probably smart enough to discard the time info. OK, I concede :-) – Gary McGill Jul 24 '09 at 14:16
  • The 0 is indeed an implicit conversion from a numeric type (INT I would guess) to a DATETIME. Because it's a constant expression, however, the optimiser can do that at compile time for Stored Procedures and only needs to do it once for dynamically execute SQL. In short, there is a one time overhead for that, the FLOAT based query has the equivilent overhead for every Row. – MatBailie Jul 26 '09 at 15:03
  • Casting to float is terribly unprecise. This answer should be deleted. Nobody should use this code. – usr Jun 03 '12 at 18:57
  • 3
    Not to mention that it's not safe to cast to float and back to datetime--float doesn't have enough precision. Therefore I think it can't be recommended at all. [See this post for more detail](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991). – ErikE Oct 29 '13 at 04:25
8

Here's yet another answer, from another duplicate question:

SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime) 

This magic number method performs slightly faster than the DATEADD method. (It looks like ~10%)

The CPU Time on several rounds of a million records:

DATEADD   MAGIC FLOAT
500       453
453       360
375       375
406       360

But note that these numbers are possibly irrelevant because they are already VERY fast. Unless I had record sets of 100,000 or more, I couldn't even get the CPU Time to read above zero.

Considering the fact that DateAdd is meant for this purpose and is more robust, I'd say use DateAdd.

Community
  • 1
  • 1
Jeff Meatball Yang
  • 37,839
  • 27
  • 91
  • 125
  • 2
    That is horrible. I'd never put my data at risk like this. Who knows if this is correct for *all* datetimes, not just the ones you tested. – usr Jun 03 '12 at 18:58
  • @usr Oh, it's correct, it's just a magic number and shouldn't be used for that reason. If you want to check its correctness, just stuff all the possible dates for one day in a table and check the results! Also [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 information. – ErikE Oct 29 '13 at 04:28
  • @ErikE good point. Your answer provides the possibility of using `'12:00:00.003'` which I think is much better, though. – usr Oct 29 '13 at 07:12
6
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)
Sirko
  • 72,589
  • 19
  • 149
  • 183
Byju
  • 187
  • 2
  • 5
6

I really like:

[date] = CONVERT(VARCHAR(10), GETDATE(), 120)

The 120 format code will coerce the date into the ISO 8601 standard:

'YYYY-MM-DD' or '2017-01-09'

Super easy to use in dplyr (R) and pandas (Python)!

emehex
  • 9,874
  • 10
  • 54
  • 100
3

BEWARE!

Method a) and b) does NOT always have the same output!

select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)

Output: 2014-01-01 00:00:00.000

select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)

Output: 2013-12-31 00:00:00.000

(Tested on MS SQL Server 2005 and 2008 R2)

EDIT: According to Adam's comment, this cannot happen if you read the date value from the table, but it can happen if you provide your date value as a literal (example: as a parameter of a stored procedure called via ADO.NET).

broslav
  • 555
  • 1
  • 5
  • 10
  • 1
    .999 cannot be stored in SQL Server in a `DATETIME` column. The highest available is .997 From: http://msdn.microsoft.com/en-us/library/ms187819.aspx you'll see that the values are rounded to have the thousandth place to 0, 3, or 7. The OP will not see the value from your test in their tables. – Adam Wenger Jan 20 '14 at 14:40
  • You are correct. I didn't mean to post this as an answer to the OP question, but as a comment for others to see, but I only had 11 reputation points and 15 is needed for commenting. – broslav Jan 22 '14 at 13:42
  • In your first snippet the string constant is implicitly converted to a datetime, in your second one it remains a string (and the 113 is just ignored). – Andriy M Jan 28 '14 at 16:11
2

See this question:
How can I truncate a datetime in SQL Server?

Whatever you do, don't use the string method. That's about the worst way you could do it.

Community
  • 1
  • 1
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Thanks, I figured this had to have been asked before. Strange though that my experiments pointed out that the float method is actually slower by 3.5% on SQL Server 2008 than the dateadd(dd,0, datediff(dd,0, getDate())) method. I did run my tests many times for each method and the database server was unused for anything else at the time. – Stephen Perelson Jul 24 '09 at 13:48
  • Let's just say that I'm skeptical of benchmarks done by anyone who hasn't demonstrated that they do benchmarks regularly and in a very scientific way as part of their job. Even Thomas' benchmark in the link by gbn has some obvious problems when you look at it. That doesn't make it wrong necessarily, just not definitive. The cast/floor/cast method was the accepted fastest way for a very long time, and I suspect it was once indisputably true. That said, I am starting to reconsider it; especially for sql server 2008, where it's completely unnecessary anyway. – Joel Coehoorn Jul 24 '09 at 14:44
  • 1
    The string method is extremely easy to use, to read, and to remember. Those are very important factors which I think you are underestimating! – Ben Jan 31 '12 at 12:36
  • @Ben - easier to read than "CAST( x as Date)" ? The string method is also wrong because it doesn't always work. Deploy your database to a server with a different collation, and you're in big trouble. – Joel Coehoorn Jan 31 '12 at 16:23
  • 1
    @JoelCoehoorn, convert style 121 is called "ODBC Canonical". It does not vary with collation or locale. The string trick is also easy to generalise to year, year+month, day, hour or minute. – Ben Jan 31 '12 at 18:58
  • 1
    @Ben The string trick teaches developers to use string conversions. They *work*, but date math is far, far superior, for many reasons, not the least of which is speed--but even more, for what learning to work with the dates-as-numbers confers on the developer and his mental abilities to be fluid with number manipulation in code. – ErikE Oct 29 '13 at 04:27
2

For me the code below is always a winner:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));
ajacian81
  • 7,419
  • 9
  • 51
  • 64
  • 1
    Essentially same as [@Gary McGill's suggestion](http://stackoverflow.com/questions/1177449/best-approach-to-remove-time-part-of-datetime-in-sql-server#1177479). – Andriy M Dec 21 '12 at 18:12
  • 1
    Casting as float [is not safe](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991). – ErikE Oct 29 '13 at 04:29
2

select CONVERT(char(10), GetDate(),126)

Diego
  • 2,238
  • 4
  • 31
  • 68
  • What is the principal difference of your suggestion from the method mentioned in @broslav's answer or from the method that was determined as **slowest** in [this thread](http://stackoverflow.com/questions/133081/most-efficient-way-in-sql-server-to-get-date-from-datetime "Most efficient way in SQL Server to get date from date+time?") (same link as in the accepted answer)? – Andriy M Mar 24 '14 at 15:35
2

Already answered but ill throw this out there too... this suposedly also preforms well but it works by throwing away the decimal (which stores time) from the float and returning only whole part (which is date)

 CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)

second time I found this solution... i grabbed this code off

Carter Cole
  • 918
  • 9
  • 16
  • 1
    Converting to float [is not safe](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991). – ErikE Oct 29 '13 at 04:35
2
CAST(round(cast(getdate()as real),0,1) AS datetime)

This method does not use string function. Date is basically a real datatype with digits before decimal are fraction of a day.

this I guess will be faster than a lot.

Christian Specht
  • 35,843
  • 15
  • 128
  • 182
  • 1
    Casting as float [is not safe](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991). – ErikE Oct 29 '13 at 04:28
1

Strip time on inserts/updates in the first place. As for on-the-fly conversion, nothing can beat a user-defined function maintanability-wise:

select date_only(dd)

The implementation of date_only can be anything you like - now it's abstracted away and calling code is much much cleaner.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • I once devised a trigger to scrub times from selected columns. If the data can't be bad, you don't have to clean it. – Philip Kelley Jul 24 '09 at 14:21
  • 2
    There is a downside to the UDF approach, they're not SARGable. If used in JOINs or WHERE clauses, the optimiser can't use INDEXes to improve performance. Using the DATEADD/DATEDIFF approach, however, is SARGable and will be able to benefit from INDEXes. (Apparently the FLOAT method is SARGable too) – MatBailie Jul 29 '09 at 11:55
  • 1
    @MatBailie I beg to differ! UDFs are definitely not SARGable, but neither is Dateadd nor is Convert to float! `WHERE DateAdd(DateDiff(Column)) = @DateValue` won't use an index. On the other hand, `WHERE Column >= dbo.UDF(@DateValue) AND Column < dbo.UDF(@DateValue + 1)` *is* SARGable. So be careful how you put it. – ErikE Oct 29 '13 at 04:34
1

I think that if you stick strictly with TSQL that this is the fastest way to truncate the time:

 select convert(datetime,convert(int,convert(float,[Modified])))

I found this truncation method to be about 5% faster than the DateAdd method. And this can be easily modified to round to the nearest day like this:

select convert(datetime,ROUND(convert(float,[Modified]),0))
Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
Jamie G
  • 81
  • 1
  • 2
  • Converting to float [is not safe](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-server/3696991#3696991). – ErikE Oct 29 '13 at 04:31
1

How about select cast(cast my_datetime_field as date) as datetime)? This results in the same date, with the time set to 00:00, but avoids any conversion to text and also avoids any explicit numeric rounding.

Dr. Andrew
  • 2,532
  • 3
  • 26
  • 42
  • 1
    Alread suggested in these answers: http://stackoverflow.com/a/17449578/569436 http://stackoverflow.com/a/10451347/569436 http://stackoverflow.com/a/19541838/569436 http://stackoverflow.com/a/1177529/569436 – Mikael Eriksson Mar 24 '14 at 08:58
  • They are not the same. The other answers suggested casting it to a date *with no time component* and leave it like that. My posting sets it to a datetime with the time at midnight. There is a big difference; try exporting to MS Excel and you'll see that it handles the datetime much better than date. – Dr. Andrew Mar 25 '14 at 09:22
  • The first one is exactly the same. – Mikael Eriksson Mar 25 '14 at 09:38
  • Ok, yes, I do see that one now. I will be happy to remove my answer as a duplicate, if necessary. – Dr. Andrew Mar 25 '14 at 11:07
1

Just in case anyone is looking in here for a Sybase version since several of the versions above didn't work

CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
  • Tested in I SQL v11 running on Adaptive Server 15.7
chancrovsky
  • 582
  • 3
  • 11
Alan
  • 21
  • 1
  • This is better fit as an edit on the accepted answer. With 20 other answers this will be buried and nigh unfindable. Also the accepted answer makes mention of using `cast`: _For SQL Server 2008+, you can CAST to date. Or just use date so no time to remove._ – EWit Sep 24 '14 at 13:03
  • It would be best to post this as an answer to an equivalent Sybase question. If there is no such question, you are free to create one (and answer it yourself). – Andriy M Sep 25 '14 at 05:36
  • Besides, it is pointless to specify a third parameter to CONVERT when you are converting a `datetime` to `date`: neither of those has an inherent format. – Andriy M Sep 25 '14 at 05:40
1

Here I made a function to remove some parts of a datetime for SQL Server. Usage:

  • First param is the datetime to be stripped off.
  • Second param is a char:
    • s: rounds to seconds; removes milliseconds
    • m: rounds to minutes; removes seconds and milliseconds
    • h: rounds to hours; removes minutes, seconds and milliseconds.
    • d: rounds to days; removes hours, minutes, seconds and milliseconds.
  • Returns the new datetime

create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end

Adam Konieska
  • 2,805
  • 3
  • 14
  • 27
Max Vargas
  • 396
  • 3
  • 5
  • Thanks Andriy! I didn't know my recommendation wasn't that efficient. At least it works, but you are right. – Max Vargas Jun 26 '15 at 20:53
1

I think you mean cast(floor(cast(getdate()as float))as datetime)

real is only 32-bits, and could lose some information

This is fastest cast(cast(getdate()+x-0.5 as int)as datetime)

...though only about 10% faster(about 0.49 microseconds CPU vs. 0.58)

This was recommended, and takes the same time in my test just now: DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

In SQL 2008, the SQL CLR function is about 5 times faster than using a SQL function would be, at 1.35 microseconds versus 6.5 microsections, indicating much lower function-call overhead for a SQL CLR function versus a simple SQL UDF.

In SQL 2005, the SQL CLR function is 16 times faster, per my testing, versus this slow function:

create function dateonly (  @dt datetime )
returns datetime
as
begin
return cast(floor(cast(@dt as float))as int)
end
amesh
  • 1,311
  • 3
  • 21
  • 51
Aaron West
  • 11
  • 1
0

I, personally, almost always use User Defined functions for this if dealing with SQL Server 2005 (or lower version), however, it should be noted that there are specific drawbacks to using UDF's, especially if applying them to WHERE clauses (see below and the comments on this answer for further details). If using SQL Server 2008 (or higher) - see below.

In fact, for most databases that I create, I add these UDF's in right near the start since I know there's a 99% chance I'm going to need them sooner or later.

I create one for "date only" & "time only" (although the "date only" one is by far the most used of the two).

Here's some links to a variety of date-related UDF's:

Essential SQL Server Date, Time and DateTime Functions
Get Date Only Function

That last link shows no less than 3 different ways to getting the date only part of a datetime field and mentions some pros and cons of each approach.

If using a UDF, it should be noted that you should try to avoid using the UDF as part of a WHERE clause in a query as this will greatly hinder performance of the query. The main reason for this is that using a UDF in a WHERE clause renders that clause as non-sargable, which means that SQL Server can no longer use an index with that clause in order to improve the speed of query execution. With reference to my own usage of UDF's, I'll frequently use the "raw" date column within the WHERE clause, but apply the UDF to the SELECTed column. In this way, the UDF is only applied to the filtered result-set and not every row of the table as part of the filter.

Of course, the absolute best approach for this is to use SQL Server 2008 (or higher) and separate out your dates and times, as the SQL Server database engine is then natively providing the individual date and time components, and can efficiently query these independently without the need for a UDF or other mechanism to extract either the date or time part from a composite datetime type.

CraigTP
  • 44,143
  • 8
  • 72
  • 99
  • Using a UDF can be good in some situations (like when scrubbing parameters). But in most situations it is an *awful* solution--running a UDF once for each row is a way to just *kill* the performance of a query, without any need for it! – ErikE Oct 29 '13 at 04:30
  • @ErikE - I don't disagree, Erik, UDF's are performance killers which is why I say that, if you can use SQL Server 2008 or above and use a built-in datatype that does this for you, that will be the best solution (both in terms of achieving what's required and in terms of performance). If you're stuck with an older version of SQL Server that doesn't natively support this, you're going to give up _something_ in order to achieve your requirements. – CraigTP Oct 29 '13 at 07:12
  • True. It would be nice if the database engine gave us something that was SARGable, but easier to express. In the meantime, if you're looking for a value that's any time during a whole day, this is still the best solution (for at least older versions of SQL): `WHERE DateColumn >= {TimeTruncatingExpression}(@DateValue) AND DateColumn < {TimeTruncatingExpression}(@DateValue + 1)`. I felt like I had to say something since you said "I almost always use UDFs" didn't explain any of the drawbacks, nor the way to make a date-only query SARGable. – ErikE Oct 29 '13 at 18:12
  • @ErikE - No worries, Erik. When I've used UDF's, I've either been working with small data sets where performance isn't paramount, or more likely I've been filtering the query against the "raw" date field (to ensure sargability) but selecting the column with the UDF applied. As these are usually small datasets once filtered, running the UDF over this small number of records isn't such a performance hit. That said, you do raise a very good point and I've updated my answer to reflect this. – CraigTP Oct 30 '13 at 09:16
0

If possible, for special things like this, I like to use CLR functions.

In this case:

[Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime DateOnly(SqlDateTime input)
    {
        if (!input.IsNull)
        {
            SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);

            return dt;
        }
        else
            return SqlDateTime.Null;
    }
tjeuten
  • 649
  • 9
  • 28
-5

I would use:

CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
) 

Thus effectively creating a new field from the date field you already have.

Jonathan
  • 20,053
  • 6
  • 63
  • 70
Jabu
  • 13
  • 1
  • 2
    Why would you do that? Do you think that extracting bits from a `datetime` value, converting them to strings, concatenating those together and finally converting the result back to `datetime` is better than e.g. performing direct calculations on the original `datetime` (the `DATEADD`/`DATEDIFF` method)? – Andriy M Dec 26 '13 at 09:46
  • Also, what are `MM` and `DD`? There are no such functions in SQL Server. – Andriy M Dec 26 '13 at 09:46