在SQL Server中从datetime字段中删除时间部分时,哪种方法提供了最佳性能?

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

or

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

第二种方法确实发送了更多的字节,但这可能没有转换速度那么重要。

两者看起来也都非常快,但在处理数十万行或更多行的时候,速度可能会有所不同。

此外,是否可能有更好的方法来消除SQL中datetime的时间部分?


当前回答

小心!

方法a)和b)并不总是有相同的输出!

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

输出:2014-01-01 00:00:00.000

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

输出:2013-12-31 00:00:00.000

(在MS SQL Server 2005和2008 R2上测试)

编辑:根据Adam的评论,如果从表中读取日期值,则不会发生这种情况,但如果将日期值作为文本提供(例如:作为通过ADO.NET调用的存储过程的参数),则会发生这种情况。

其他回答

把插入/更新的时间放在首位。至于动态转换,没有什么能比得上用户定义函数的可维护性:

select date_only(dd)

date_only的实现可以是你喜欢的任何东西——现在它被抽象了,调用代码更加简洁。

我会用:

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

因此,有效地从已有的日期字段创建一个新字段。

在这里,我做了一个函数来删除SQL Server的日期时间的某些部分。用法:

第一个参数是要剥离的datetime。 第二个参数是char类型: S:转到秒;删除毫秒 M:数到分钟;删除秒和毫秒 H:转到小时;删除分钟、秒和毫秒。 D:轮到天;删除小时、分钟、秒和毫秒。 返回新的日期时间

创建函数dbo。uf_RoundDateTime(@dt作为datetime, @part作为char) 返回日期时间 作为 开始 如果CHARINDEX(@part, 'smhd',0) = 0返回@dt; 返回演员( 案例@part 当's'时,convert(varchar(19), @dt, 126) 当'm'时,则convert(varchar(17), @dt, 126) + '00' 当'h'时,则convert(varchar(14), @dt, 126) + '00:00' 当'd'时,convert(varchar(14), @dt, 112) 结束为datetime) 结束

SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)

...根据下面的评论,这不是一个好的解决方案。

我想删除这个答案,但我把它留在这里作为一个反例,因为我认为评论者对为什么它不是一个好主意的解释仍然有用。

对我来说,下面的代码总是一个赢家:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));