2016-03-01 115 views
-2

我有一个小问题与我的查询。整个查询实际上有点长,因为它包含一个UNION ALLSQL Server 2012 - 选择查询闰年

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()) 

所以,我有这个奇妙的查询。一切都运行正常,直到用户在tblIntake中输入ENROLLDATE的闰年日期。我将如何去修复它?我的另一个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 

编辑:

收到此错误,当我运行查询

消息242,级别16,状态3,第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毕竟

编辑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到日,月,年,多年来它使用获取日期,请参见下面的*** ****

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

返回的错误是什么?你有什么尝试? – AXMIM

+1

去修理... *什么*?怎么了?它是否打破了一个错误?如果是这样,那么信息是什么?你会得到意想不到的结果?如果是这样,请描述。 –

+0

@BobKaufman请参阅编辑。我没有02/29/2016测试它,它工作正常,如果我测试它 - 得到这个错误。 – FatBoySlim7

回答

3

如果我明白你在这里试图做什么,你可以大大简化这一点。请注意,我在别处使用了别名,而不是一遍又一遍地重复表名。此外,我使用日期名称而不是缩写,因为它们更清晰。最后但并非最不重要的,我只是使用现有的日期时间值。我将它们转换为日期数据类型,因为现有逻辑正在将它转换为日期值以避免时间部分。这在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()) 
+0

这看起来不错,但请参阅编辑。我想我正在努力重新编写查询,使其更简单,因为它不会做任何复杂的事情。就像你说的那样,这个查询是在较老的系统中使用的,并且是为这个报告导入的请参阅编辑。 – FatBoySlim7

+0

你知道这应该做什么吗?还是你必须把别人的混乱分解成可用的东西?如果你知道规则,我们可以使这更简单。解密它更具挑战性。 –

+0

这是一个正在工作的查询。跳跃日期是什么导致我重写它。基本上,这个应该做的就是在未来的45天内把所有的名字和显示名字(第一,最后,MI)的'6个月预约'交给谁。 – FatBoySlim7

2

我与dateadd取代所有这些日期部分和convert S,是这样的:

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