在SQL Server中无需时间比较日期的最佳方法

时间:2012-02-16 09:29:58

标签: sql sql-server datetime utc

select * from sampleTable 
where CONVERT(VARCHAR(20),DateCreated,101) 
=     CONVERT(VARCHAR(20),CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME),101)

我想比较没有时间的日期

以上查询是否可以?或者你建议的其他更好的解决方案

  • 我正在使用SQL Server 2005
  • 在服务器上以UTC格式保存的日期
  • 针对此数据的用户属于不同的时区

8 个答案:

答案 0 :(得分:23)

不要使用转换 - 无缘无故地涉及字符串。一个技巧是日期时间实际上是一个数字,而日期是整数部分(时间是小数部分);因此,这一天是价值的 FLOOR :这只是数学,而不是字符串 - 更快

declare @when datetime = GETUTCDATE()
select @when -- date + time
declare @day datetime = CAST(FLOOR(CAST(@when as float)) as datetime)
select @day -- date only

在您的情况下,无需转换回日期时间;并且使用范围允许最有效的比较(特别是如果索引):

declare @when datetime = 'Feb 15 2012  7:00:00:000PM'
declare @min datetime = FLOOR(CAST(@when as float))
declare @max datetime = DATEADD(day, 1, @min)

select * from sampleTable where DateCreated >= @min and DateCreated < @max

答案 1 :(得分:12)

简单转换为Date将解决问题。

DECLARE @Date datetime = '04/01/2016 12:01:31'

DECLARE @Date2 datetime = '04/01/2016'

SELECT CAST(@Date as date)

SELECT CASE When (CAST(@Date as date) = CAST(@Date2 as date)) Then 1 Else 0 End

答案 2 :(得分:4)

SELECT .......
FROM ........
WHERE 
CAST(@DATETIMEVALUE1 as DATE) = CAST(@DATETIMEVALUE2 as DATE)

缺点是您正在构建过滤器列。

如果过滤器列上有索引,那么,由于您正在进行转换,因此SQL引擎无法再使用索引来更有效地过滤日期。

答案 3 :(得分:3)

描述

不要将日期转换为varchar并进行比较,因为字符串比较不快。

如果您使用>=<来过滤DateCreated列,速度会快得多。

如果您没有参数(例如样本中的字符串),则应使用ISO格式<Year><Month><Day>

示例

根据您的样本

DECLARE @startDate DateTime
DECLARE @endDate DateTime

SET @startDate = '20120215'
SET @endDate = DATEADD(d,1,@startDate)

SELECT * FROM sampleTable 
WHERE DateCreated >= @startDate AND DateCreated < @endDate

更多信息

答案 4 :(得分:1)

SELECT * from sampleTable  
WHERE 
datediff(day, DateCreated,CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME))  = 0    

在性能测试最明显的解决方案之后,这是我的结果:

declare @mytime int, @othertime int, @othertime2 int
declare @i int = 0
declare @dummy int
declare @emptyloop int
declare @time datetime = getdate()

while @i < 100000
begin
set @i = @i + 1
end
set @emptyloop = datediff(microsecond, @time, getdate())

set @time = getdate()

set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE datediff(day, 0,getdate())  = 0
set @i = @i + 1
end
select @othertime = datediff(microsecond, @time, getdate()) - @emptyloop

set @time = getdate()

set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE datediff(day, 0,@i)  = 0
set @i = @i + 1
end
set @mytime = datediff(microsecond, @time, getdate()) - @emptyloop


declare @when datetime = 'Feb 15 2012  7:00:00:000PM' 
declare @min datetime = FLOOR(CAST(@when as float)) 
declare @max datetime = DATEADD(day, 1, @min)  
set @time = getdate()
set @i = 0
while @i < 100000
begin
select @dummy = 1 WHERE @i >= @min and @i < @max
set @i = @i + 1
end
set @othertime2 = datediff(microsecond, @time, getdate()) - @emptyloop


select @mytime mytime, @othertime othertime, @othertime2 othertime2

结果:

mytime      othertime   othertime2
----------- ----------- -----------
117000      144000      147000

我尽可能准确地做到了,对不起的评论感到抱歉。随意运行测试以检查整体结果。

答案 5 :(得分:-1)

使用112 CONVERT的格式

select * 
from sampleTable 
where 
  CONVERT(VARCHAR(20),DateCreated,112) 
=     CONVERT(VARCHAR(20),CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME),112)

如果您的sql server版本2008+使用DATE类型

select * from sampleTable 
where CONVERT(DATE,DateCreated) 
=     CONVERT(DATE,CAST('Feb 15 2012  7:00:00:000PM' AS DATETIME))

答案 6 :(得分:-1)

声明@DateToday Date ='2019-10-1'; 打印@DateToday;

打印Abs(datediff(day,@ DateToday,CAST('Oct 1 2019 7:00:00:000PM'DATETIME)))<3

这是比较三天。

我在SQL Server 2014上对此进行了测试,它可以正常工作。

答案 7 :(得分:-3)

select * from sampleTable 
where date_created ='20120215'

这也会将您的列与特定日期进行比较 没有花时间考虑