我的查询有点问题。整个查询实际上有点长,因为它包含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()
现在以这种方式更容易完成,因为他确实把它拆开了,我怎么能用我的完整注册日期来完成它。
答案 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