2012-03-31 45 views
0

我有一个具有以下字段的表(其中包括)查询两个日期

TagID 
TagType 
EventDate 
EventType 

事件类型可以用“通过验收”,“检验不合格”或者“修理”填充之间创建记录(有其实很多人,但简化到我的问题)

标签可以去一个失败的检查和最终修复之间的许多个月......在这种状态,他们被视为“等待修复”。即使在识别失败后,标签仍然每个月都会被检查。 (而且要说清楚,“检查失败”并不意味着被检查的项目根本无法工作......它仍然有效,只是不能达到100%的能力......这就是为什么我们仍然对其进行检查的原因)。

我需要创建一个查询,通过TagType,Month和Year来计算正在等待修复的标签的数量。最终的结果表是这样的,例如

TagType  EventMonth  EventYear  CountofTagID 
xyz    1   2011    3 
abc    1   2011    2 
xyz    2   2011    2>>>>>>>>>>>>indicating a repair had been made since 1/2011 
abc    2   2011    2 
and so on 

的“待修”状态应在每月

这最后一天进行评估是完全莫名其妙我...

一个想法,我已经是开发返回的查询:

TagID, 
TagType, 
FailedInspectionDate, and 
NextRepairDate, 

然后尝试做一些事情,加强通在两个日期之间的月份,但似乎w ^非常低效。

任何帮助将不胜感激。

更新
多一点研究,并从问题考虑一下不同的给了我下面的办法休息。我相信它不高效或优雅,但它的工作原理。将不胜感激。

declare @counter int 
declare @FirstRepair date 
declare @CountMonths as int 

set @FirstRepair = (<Select statement to find first repair across all records>) 
set @CountMonths = (<select statement to find the number of months between the first repair across all records and today>) 
--clear out the scratch table 
delete from dbo.tblMonthEndDate 
set @counter=0 
while @counter <[email protected] --fill the scratch table with the date of the last day of every month from the @FirstRepair till today 
begin 
insert into dbo.tblMonthEndDate(monthenddate) select    dbo.lastofmonth(dateadd(m,@counter, @FirstRepair)) 
set @counter = @counter+1 
end 
--set up a CTE to get a cross join between the scratch table and the view that has the associated first Failed Inspection and Repair 
;with Drepairs_CTE (FacilityID, TagNumber, CompType, EventDate) 
AS 
(
SELECT dbo.vwDelayedRepairWithRepair.FacilityID,  dbo.vwDelayedRepairWithRepair.TagNumber, dbo.vwDelayedRepairWithRepair.CompType, 
      dbo.tblMonthEndDate.MonthEndDate 
FROM dbo.vwDelayedRepairWithRepair INNER JOIN 
      dbo.tblMonthEndDate ON dbo.vwDelayedRepairWithRepair.EventDate <= dbo.tblMonthEndDate.MonthEndDate AND 
      dbo.vwDelayedRepairWithRepair.RepairDate >= dbo.tblMonthEndDate.MonthEndDate 
) 
--use the CTE to build the final table I want 
Select FacilityID, CompType, Count(TagNumber), MONTH(EventDate),  YEAR(EventDate), 'zzz' as EventLabel 
FROM Drepairs_CTE 
GROUP BY FacilityID, CompType, MONTH(EventDate), YEAR(EventDate)`  

结果最终设置如下:

FacilityID CompType Count Month  Year Label 
1  xyz 2 1 2010 zzz 
1  xyz 1 2 2010 zzz 
1  xyz 1 7 2009 zzz 
+1

虽然结果表格非常清晰,但通过提供当前表格中的样本数据可以更容易地了解如何得到这些结果。尝试提供不同的例子,例如,如果标签被修复,然后修复,然后再次中断并再次修复,会发生什么?谢谢 – 2012-03-31 16:21:41

+0

它是一个永远绿色的清单,所以它几乎可以确保中断,修复,再次中断,再次修复情况将会发生......重复。上述示例的源数据对于张贴(和阅读)来说是非常繁琐的,但总的来说看起来像这样: – 2012-03-31 19:17:47

+0

它是一个永远绿色的列表,所以它几乎可以确保中断,修复,再次中断,修复再一次情景会发生......重复。以上示例的源数据对于张贴(和读取)将非常繁琐,但通常看起来像这样:TagNumber CompType EventDate EventType 0001 xyz 2011/1/10检测失败 0001 xyz 2011/2/10成功修复 0001 xyz 2011/3/10通过检查 – 2012-03-31 19:24:03

回答

1

这里是一个递归CTE产生开始在修表最小日期和最大日期结束的间隔几个月的最后日期表。

;with tableOfDates as (
    -- First generation returns last day of month of first date in repair database 
    -- and maximum date 
    select dateadd (m, datediff (m, 0, min(eventDate)) + 1, 0) - 1 startDate, 
     max(eventDate) endDate 
    from vwDelayedRepairWithRepair 
    union all 
    -- Last day of next month 
    select dateadd (m, datediff (m, 0, startDate) + 2, 0) - 1, 
     endDate 
    from tableOfDates 
    where startDate <= endDate 
) 
select * 
from tableOfDates 
-- If you change the CTE, 
-- Set this to reasonable number of months 
-- to prevent recursion problems. 0 means no limit. 
option (maxrecursion 0) 

从tableOfDates的EndDate列将被忽略,因为它仅作为上限。如果创建的UDF返回间隔中的所有日期,请在选择列表中省略endDate,或者将其从CTE中移除并替换为参数。

Sql Fiddle playground is here