4 sql sql-server sql-server-2008
我需要查找员工的周年纪念日和周年纪念日,并每隔14天发送电子邮件。但是,如果开始日期和结束日期在不同的年份,则在使用以下查询时,12月的最后一周有问题。
Select * from Resource
where (DATEPART(dayofyear,JoinDate)
BETWEEN DATEPART(dayofyear,GETDATE())
AND DATEPART(dayofyear,DateAdd(DAY,14,GETDATE())))
Run Code Online (Sandbox Code Playgroud)
相反,比较到的dayofyear(在1月1日,其复位至零,并在合理范围内的年底14天查询休息),你可以更新员工的joindate成为查询的目的当年,只是比较实际日期
Select * from Resource
-- Add the number of years difference between joinDate and the current year
where DATEADD(year,DATEDIFF(Year,joinDate,GetDate()),JoinDate)
-- compare to range "today"
BETWEEN GetDate()
-- to 14 days from today
AND DATEADD(Day,14,GetDate())
-- duplicate for following year
OR DATEADD(year,DATEDIFF(Year,joinDate,GetDate())+1,JoinDate) -- 2016-1-1
BETWEEN GetDate()
AND DATEADD(Day,14,GetDate())
Run Code Online (Sandbox Code Playgroud)
测试查询:
declare @joindate DATETIME='2012-1-1'
declare @today DATETIME = '2015-12-26'
SELECT @joinDate
where DATEADD(year,DATEDIFF(Year,@joinDate,@today),@JoinDate) -- 2015-1-1
BETWEEN @today -- 2015-12-26
AND DATEADD(Day,14,@today) -- 2016-01-09
OR DATEADD(year,DATEDIFF(Year,@joinDate,@today)+1,@JoinDate) -- 2016-1-1
BETWEEN @today -- 2015-12-26
AND DATEADD(Day,14,@today) -- 2016-01-09
Run Code Online (Sandbox Code Playgroud)
(H / T @Damien_The_Unbeliever进行简单修复)
上面的代码正确地选择了joinDate1月第一周的。(请注意,@today由于Ive没有设法发明时间旅行,所以我不得不捏造)。
上述解决方案还应解决原始解决方案中存在的leap年问题。
更新资料
您在评论中表示了选择AnniversaryDate和Years服务的要求,您需要应用一些CASE逻辑来确定是否在选择中添加1(年或日期)
select *,
CASE
WHEN DATEADD(YEAR,DATEDIFF(Year,JoinDate,GETDATE()),JoinDate) < GetDate()
THEN DATEDIFF(Year,JoinDate,GETDATE())+1
ELSE DATEDIFF(Year,JoinDate,GETDATE())
END as [Years],
CASE WHEN DATEADD(YEAR,DATEDIFF(Year,JoinDate,GETDATE()),JoinDate) < GetDate()
THEN DATEADD(YEAR,DATEDIFF(Year,JoinDate,GETDATE())+1,JoinDate)
ELSE DATEADD(YEAR,DATEDIFF(Year,JoinDate,GETDATE()),JoinDate)
end as [AnniversaryDate]
.... // etc
Run Code Online (Sandbox Code Playgroud)