在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的时间部分?


当前回答

我非常喜欢:

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

120格式代码将强制将日期转换为ISO 8601标准:

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

在dplyr (R)和pandas (Python)中超级容易使用!

其他回答

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

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

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

我认为如果你严格使用TSQL,这是截断时间的最快方法:

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

我发现这种截断方法比DateAdd方法快5%左右。这可以很容易地修改为四舍五入到最近的一天,像这样:

select convert(datetime,ROUND(convert(float,[Modified]),0))

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

select date_only(dd)

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

如果可能的话,对于这样的特殊情况,我喜欢使用CLR函数。

在这种情况下:

[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;
    }
CAST(round(cast(getdate()as real),0,1) AS datetime)

此方法不使用字符串函数。日期基本上是一种真实的数据类型,小数点前的数字是一天的小数。

我猜这个会比很多快。