SQL Server 2012 - 选择查询闰年

时间:2016-03-01 19:24:58

标签: sql-server date datetime select

我的查询有点问题。整个查询实际上有点长,因为它包含UNION ALL

SELECT 'ITV' = CASE WHEN tblIntake.StaffID Is Null THEN '<Unknown>' ELSE
(tblStaffMember.StaffLast + ', ' + tblStaffMember.StaffFirst + CASE WHEN
tblStaffMember.StaffMI Is Null THEN '' ELSE ' ' + tblStaffMember.StaffMI END) END, 
tblMember.[LAST], tblMember.[FIRST], 
'DueDate' = DATEADD(m, 6,CAST(CONVERT(Varchar(10),
MONTH(tblIntake.EnrollDate)) + '/' + CONVERT(Varchar(10),
DAY(tblIntake.EnrollDate)) + '/' + CONVERT(Varchar(10),YEAR(GETDATE()))As
 DateTime)), 'Type' = '6 Month Appt' 

From tblIntake LEFT JOIN tblStaffMember ON tblIntake.StaffID =
tblStaffMember.StaffID LEFT JOIN tblMember ON 
tblIntake.KEY = tblMember.KEY 

Where tblIntake.UnEnrollDate Is Null AND
DATEADD(m,6,CAST(CONVERT(Varchar(10),MONTH(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),DAY(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),YEAR(GETDATE()))As DateTime)) > GETDATE() AND 
DATEADD(m, 6,CAST(CONVERT(Varchar(10),MONTH(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),DAY(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),YEAR(GETDATE()))As DateTime)) <= DATEADD(d, 45, GETDATE()) 

所以,我有这个奇妙的问题。一切都运行正常,直到用户在ENROLLDATE中输入tblIntake的闰年日期。我该怎么办呢?我的另一个UNION执行相同的SELECT语句,但是当它执行

时除外
CONVERT(VARCHAR(10),YEAR(GetDate()-1)) as DateTime > '4th line from the bottom
CONVERT(VARCHAR(10),YEAR(GetDate()-1)) as DateTime > '2nd line from the bottom

编辑:

运行查询时收到此错误

  

Msg 242,Level 16,State 3,Line 1
  将varchar数据类型转换为日期时间数据类型会导致超出范围的值。

我尝试运行单独的查询,看起来我只是在我这样做时才收到错误..

 CONVERT(VARCHAR(10),YEAR(GetDate()-1)) as DateTime > '4th line from the bottom
CONVERT(VARCHAR(10),YEAR(GetDate()-1)) as DateTime > '2nd line from the bottom

UNION ALL

之后

编辑2:

我一直在研究肖恩的答案,这更有意义。这是我得到的代码......

SELECT 'CSC' = case when tblIntake.staffID is null Then '<notIndicated>' Else (tblStaffMember.staffLast + ',' + tblStaffMember.StaffFirst + case when tblStaffMember.staffMI is null then '' else ' ' + tblStaffMember.staffMI END)end  
, tblMember.[Last], tblMember.[First]
,'Due' = DateADD(m,6,cast(tblIntake.enrolldate as datetime))
,'Type' = '6 Month Review'
from tblMembEnrollment
left join tblStaffMember on tblIntake.staffID = tblStaffMember.staffID 
left join tblMember on tblIntake.SBkey=tblMember.sbkey
where tblIntake.unEnrollDate is null and dateAdd(m, 6, tblIntake.enrolldate)  > GETDATE()
and dateadd(m, 6, cast(tblIntake.enrolldate as DateTime))<= DateAdd(d,45,GetDate())

我看到的问题是,在旧查询中,当代码将EnrollDate拆分为几年,几年和几年时,它使用了GET DATE,请参见下面的*** ****

Where tblIntake.UnEnrollDate Is Null AND
DATEADD(m,6,CAST(CONVERT(Varchar(10),MONTH(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),DAY(tblIntake.EnrollDate)) + '/' +
CONVERT(Varchar(10),***YEAR(GETDATE()))As DateTime))*** > GETDATE()

现在以这种方式更容易完成,因为他确实把它拆开了,我怎么能用我的完整注册日期来完成它。

2 个答案:

答案 0 :(得分:3)

如果我理解你在这里尝试做什么,你可以大大简化这一点。请注意,我在任何地方都使用了别名,而不是一遍又一遍地重复表名。此外,我使用了datepart名称而不是缩写,因为它们更清晰。最后但并非最不重要的是,我只使用了现有的日期时间值。我将它们转换为日期数据类型,因为现有逻辑正在做的是将其转换为日期值以避免时间部分。这在添加date数据类型的2005之前相当普遍。我还将所有嵌套的case表达式简化为更易于阅读的内容。

SELECT 'ITV' = ISNULL(sm.StaffLast + ', ' + sm.StaffFirst + ISNULL(' ' + sm.StaffMI, ''), '<Unknown>')
    , tblMember.[LAST]
    , tblMember.[FIRST]
    , 'DueDate' = DATEADD(month, 6, convert(date, tblIntake.EnrollDate))
    , 'Type' = '6 Month Appt' 
From tblIntake i
LEFT JOIN tblStaffMember sm ON i.StaffID = sm.StaffID 
LEFT JOIN tblMember m ON i.KEY = m.KEY 
Where i.UnEnrollDate Is Null 
    AND DATEADD(month, 6, convert(date, i.EnrollDate)) > GETDATE() 
    AND DATEADD(month, 6, convert(date, i.EnrollDate)) <= DATEADD(day, 45, GETDATE()) 

- 编辑 -

随着规则的明确,我认为这应该是你正在寻找的。这样做的优点还在于可以使用SARGable,因此可以使用i.EnrollDate上的任何索引。

Where i.UnEnrollDate Is Null 
    AND convert(date, i.EnrollDate) > DATEADD(month, -6, GETDATE())
    AND convert(date, i.EnrollDate) <= DATEADD(day, -45, GETDATE())

答案 1 :(得分:2)

我会用convert替换所有这些日期部分和dateadd,例如:

declare @test datetime
set @test = '2-29-2016'

select cast(@test as varchar(11))
, cast(dateadd(mm, 6, @test) as varchar(11))
, cast(dateadd(yy, -1, @test) as varchar(11))

如果您将日期保留为日期时间,SQL Server将自动更正闰年,更短的月份等。上面的查询返回:

Feb 29 2016   Aug 29 2016   Feb 28 2015