Запрос на создание записей между двумя датами - PullRequest
0 голосов
/ 31 марта 2012

У меня есть таблица со следующими полями (среди прочих)

TagID
TagType
EventDate
EventType

EventType можно заполнить с помощью «Пройденный осмотр», «Неудачный осмотр» или «Восстановленный» (на самом деле есть много других, ноэто упрощает мою проблему)

Теги могут проходить много месяцев между неудачной проверкой и окончательным ремонтом ... в этом состоянии они считаются "ожидающими ремонта".Метки по-прежнему проверяются каждый месяц даже после того, как они были определены как потерпевшие неудачу.(и, чтобы быть ясным, «неудачная проверка» не означает, что проверяемый объект не работает вообще… он все еще работает, но не на 100% мощности… именно поэтому мы все еще проводим проверки на нем).

Мне нужно создать запрос, который по тэгам, месяцу и году подсчитывает количество тэгов, ожидающих восстановления.Таблица конечных результатов будет выглядеть следующим образом, например:

 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,

, а затем попытаться сделать что-то, что шагало через месяцы между двумя датами, но это кажется дико неэффективным.

Любая помощь будет высоко ценится.

Обновление
Немного больше исследований и отрыв от проблемы, чтобы думать об этом по-другому, дали мне следующий подход.Я уверен, что это не эффективно или элегантно, но это работает.Комментарии для улучшения будут оценены.

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 <=@CountMonths --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 Ответ

1 голос
/ 01 апреля 2012

Вот рекурсивный 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)

Столбец EndDate из tableOfDates следует игнорировать, поскольку он служит только в качестве верхней границы. Если вы создаете UDF, который возвращает все даты в интервале, пропустите endDate в списке выбора или удалите его из CTE и замените параметром.

Sql Fiddle детская площадка здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...