2

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

我知道有两种方法是相当标准的:

方法#1:

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

方法#2:

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

我是方法 #2 的忠实粉丝,因为我发现它更容易内化并且(稍微)更快。但是,有人告诉我方法 #1 是执行此操作的标准方法。我的问题是为什么?我最适合使用这两种方法中的哪一种作为从我的武器库中的日期开始一个月的方法,为什么?

4

4 回答 4

4

在 SQL Server 2008 中,我同样满意:

SELECT CONVERT(DATE, CURRENT_TIMESTAMP);

除了更简单和自记录之外,这是一个例外,可以将转换应用于列并仍然使用索引。例如,如果两者产生大致相同的性能,哪个更容易阅读?

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

比。

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

在这三种方法中,您可能会发现微小的性能差异,但恕我直言,自行测试它们的价值不大。你多久从一个单独的约会中剥离一百万次时间?您应该会发现,给定相同的语义,作为实际查询的一部分,使用 DATEDIFF 或 FLOOR 或 CONVERT 的成本不会被考虑在内。

顺便说一句,如果您将结果分配给显式 DATETIME 或 SMALLDATETIME 变量/列,或者通过 where 子句隐式执行此操作,则可以跳过 DATEADD 部分。

SELECT CONVERT(DATETIME, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP));
于 2012-06-07T03:36:19.903 回答
2

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

于 2012-06-07T03:04:30.000 回答
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'

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

于 2012-06-07T03:21:20.493 回答
1

从 getdate() 中获取月份:

SELECT DATEPART(MONTH, GETDATE())
于 2012-06-07T10:23:14.877 回答