2012-03-31 82 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