仅从日期时间开始约会 - 哪个最好?为什么?

时间:2012-06-07 02:45:06

标签: sql sql-server sql-server-2008 tsql sql-server-2005

因此,最近我的工作存在一些分歧,即从getdate()(或者从日期时间列)获取月份的最佳方式。

我知道有两种方法可以做到这一点:

方法#1:

select DateAdd(Day, 0, DateDiff(Day, 0, Getdate())) 

方法#2:

select Cast(Floor(Cast(Getdate() as Float)) as Datetime) 

我是方法#2的忠实粉丝,因为我发现它更容易内化以及(稍微)更快。但是,我被告知方法#1是这样做的标准方法。我的问题是为什么?我最好服用哪两个作为从我的武器库中约会一个月的方法以及为什么?

4 个答案:

答案 0 :(得分:4)

在SQL Server 2008中,我对以下内容感到满意:

SELECT CONVERT(DATE, CURRENT_TIMESTAMP);

除了更简单和自我记录之外,这是一个例外,其中转换可以应用于列并仍然使用索引。例如哪个更易于阅读,如果两者的收益率大致相同?

WHERE CONVERT(DATE, col) = CONVERT(DATE, CURRENT_TIMESTAMP)

Vs以上。

WHERE col >= CONVERT(DATE, CURRENT_TIMESTAMP) -- or any of your alternatives
AND col < DATEADD(DAY, 1, CONVERT(DATE, CURRENT_TIMESTAMP))

在这三种方法中,您可能会发现微小的性能差异,但是单独测试它们对IMHO没什么价值。你有多少时间孤立地从一百万次的日期中剥离时间?您应该发现,给定相同的语义,作为真实查询的一部分,使用DATEDIFF或FLOOR或CONVERT的成本不会考虑因素。

顺便说一句,如果要将结果分配给显式的DATETIME或SMALLDATETIME变量/列,或者通过where子句隐式地这样做,则可以跳过DATEADD部分。

SELECT CONVERT(DATETIME, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP));

答案 1 :(得分:2)

我相信前者更好,因为它不涉及浮点数学,只需要访问日期时间的内部存储中的第一个整数。见this as well

答案 2 :(得分:2)

我运行脚本进行测试,你的方法#1和方法#2的速度非常相似。 Charles Bretana发布的答案实际上在每次测试中都较慢。当然,这些都是相当不科学的,所以要自己测试一下。这是我写的脚本:

declare @starttime datetime
declare @endtime datetime

set @starttime = GETDATE()
print convert(varchar(30), @starttime, 109)

declare @cnt int
set @cnt = 0

declare @datevar datetime

while @cnt < 10000000
begin

    select @datevar = DateAdd(Day, 0, DateDiff(Day, 0, Getdate())) -- Replace this with whichever function you'd like to test
        , @cnt = @cnt + 1
end

set @endtime = GETDATE()
print convert(varchar(30), @endtime, 109)

print cast(datediff(ms, @starttime, @endtime) as varchar(20)) + ' ms'

只需将选择的@datevar =行替换为适当的行。在我的开发机器上,方法1和2通常在7200 - 7300毫秒内运行。 Charles发布的方法通常平均为8300 - 8500 ms

答案 3 :(得分:1)

从getdate()获取月份:

SELECT DATEPART(MONTH, GETDATE())