这是我遇到的问题:我有一个大型查询,需要比较where子句中的日期时间以查看两个日期是否在同一天。我当前的解决方案很糟糕,就是将日期时间发送到UDF中,以将其转换为同一天的午夜,然后检查这些日期是否相等。当涉及到查询计划时,这是一场灾难,联接或where子句中的几乎所有UDF都是如此。这是我的应用程序中唯一无法根除函数并为查询优化器提供一些可以实际用来定位最佳索引的地方之一。
在这种情况下,将功能代码合并回查询中似乎是不切实际的。
我想我在这里缺少一些简单的东西。
这是供参考的功能。
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
我对datediff的工作方式(连续几年的同一天产生366,而不是我预期的0)的误解使我浪费了很多精力。
但是查询计划没有改变。我想我需要回到整个过程。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。