当前位置:  开发笔记 > 数据库 > 正文

有什么方法可以检查两个日期时间是否在TSQL中的同一个日历日?

如何解决《有什么方法可以检查两个日期时间是否在TSQL中的同一个日历日?》经验,为你挑选了3个好方法。

这是我遇到的问题:我有一个大型查询需要比较where子句中的日期时间,以查看两个日期是否在同一天.我当前的解决方案很糟糕,是将日期时间发送到UDF以将它们转换为同一天的午夜,然后检查这些日期是否相等.当涉及到查询计划时,这是一场灾难,几乎所有联接中的UDF或where子句都是如此.这是我的应用程序中唯一一个我无法根除函数并为查询优化器提供实际可用于查找最佳索引的地方之一.

在这种情况下,将函数代码合并回查询似乎是不切实际的.

我想我在这里缺少一些简单的东西.

这是参考功能.

if not exists (select * from dbo.sysobjects 
              where id = object_id(N'dbo.f_MakeDate') and               
              type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
  exec('create function dbo.f_MakeDate() returns int as 
         begin declare @retval int return @retval end')
go

alter function dbo.f_MakeDate
(
    @Day datetime, 
    @Hour int, 
    @Minute int
)
returns datetime
as

/*

Creates a datetime using the year-month-day portion of @Day, and the 
@Hour and @Minute provided

*/

begin

declare @retval datetime
set @retval = cast(
    cast(datepart(m, @Day) as varchar(2)) + 
    '/' + 
    cast(datepart(d, @Day) as varchar(2)) + 
    '/' + 
    cast(datepart(yyyy, @Day) as varchar(4)) + 
    ' ' + 
    cast(@Hour as varchar(2)) + 
    ':' + 
    cast(@Minute as varchar(2)) as datetime)
return @retval
end

go

更复杂的是,我正在加入时区表来检查当地时间的日期,每行可能会有所不同:

where 
dbo.f_MakeDate(dateadd(hh, tz.Offset + 
    case when ds.LocalTimeZone is not null 
    then 1 else 0 end, t.TheDateINeedToCheck), 0, 0) = @activityDateMidnight

[编辑]

我正在纳入@Todd的建议:

where datediff(day, dateadd(hh, tz.Offset + 
    case when ds.LocalTimeZone is not null 
    then 1 else 0 end, t.TheDateINeedToCheck), @ActivityDate) = 0

我对约瑟夫如何工作的误解(连续几年的同一天产生366,而不是我预期的0)导致我浪费了很多精力.

但查询计划没有改变.我想我需要回到整个事情的绘图板.



1> 小智..:

这更简洁:

where 
  datediff(day, date1, date2) = 0


为什么这有9个上升票并获得答案?它很简洁,很好,并且导致OP走上了错误的道路.由于第二个日期@ActivityDate是固定的,我们可以将数学运算到右侧并获得更好的性能.
同意@emtucifor.这个逻辑不是sql server可以理解的.

2> Mark Bracket..:

你几乎必须保持where子句的左侧清洁.所以,通常情况下,你会这样做:

WHERE MyDateTime >= @activityDateMidnight 
      AND MyDateTime < (@activityDateMidnight + 1)

(有些人更喜欢DATEADD(d,1,@ activityDateMidnight) - 但这是相同的事情).

TimeZone表虽然有点复杂.你的片段有点不清楚,但它看起来像是.DateInTable在GMT中带有时区标识符,然后你要添加偏移量来与@activityDateMidnight进行比较 - 这是当地时间.不过,我不确定ds.LocalTimeZone是什么.

如果是这种情况,那么你需要将@activityDateMidnight改为GMT.



3> jason saldo..:
where
year(date1) = year(date2)
and month(date1) = month(date2)
and day(date1) = day(date2)

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有