2012-03-31 3 views
0

J'ai une table avec les champs suivants (entre autres)requête pour créer des enregistrements entre deux dates

TagID 
TagType 
EventDate 
EventType 

EventType peut être rempli avec « passé l'inspection », « échec de l'inspection » ou « Réparé » (il y a En fait, beaucoup d'autres, mais simplifie à cela pour mon problème)

Les étiquettes peuvent aller plusieurs mois entre une inspection ratée et la réparation ultime ... dans cet état, ils sont considérés comme "en attente de réparation". Les étiquettes sont toujours inspectées chaque mois même après avoir été identifiées comme ayant échoué. (et pour être clair, une "inspection ratée" ne signifie pas que l'article inspecté ne fonctionne pas du tout ... cela fonctionne toujours, mais pas à 100% de sa capacité ... c'est pourquoi nous faisons encore des inspections dessus).

J'ai besoin de créer une requête qui compte, par TagType, Month et Year, le nombre de Tags en attente de réparation. Le tableau de résultat final ressemblerait à ceci, par exemple

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 

Le statut « en attente de réparation » devrait être évalué le dernier jour du mois

Ceci est tout à fait me déconcertant ...

On croyait que je l'avais était de développer une requête qui retourne:

TagID, 
TagType, 
FailedInspectionDate, and 
NextRepairDate, 

essayez et faire quelque chose qui est intervenu à travers les mois entre les deux dates, mais qui semble w Il est inefficace.

Toute aide serait grandement appréciée.

Mise à jour
Un peu plus de recherche, et une rupture du problème à penser différemment m'a donné l'approche suivante. Je suis sûr que ce n'est pas efficace ou élégant, mais ça marche. Des commentaires à améliorer seraient appréciés.

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

jeu de résultats ressemble finalement à ceci:

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

Bien que la table de résultat soit assez claire, il serait plus facile de comprendre comment vous avez obtenu ces résultats en fournissant des exemples de données de vos tables actuelles. Essayez de fournir différents exemples, par exemple, que se passerait-il si une étiquette était réparée, puis corrigée, puis cassée à nouveau et réparée à nouveau? Merci –

+0

C'est une liste toujours verte, donc c'est presque assuré que la pause, réparer, casser à nouveau, réparer le scénario se produira ... à plusieurs reprises.Les données source de l'exemple ci-dessus seraient extrêmement fastidieuses à poster (et à lire), mais, en général ressemblerait à ceci: –

+0

C'est une liste toujours verte, donc c'est presque assuré que la pause, corrige, casse encore, répare encore le scénario arrivera ... à plusieurs reprises. Les données source de l'exemple ci-dessus seraient extrêmement fastidieuses à poster (et à lire), mais, en général ressemblerait à ceci: TagNumber CompType EventDate EventType 0001 xyz 2011/1/10 Échec de l'inspection 0001 xyz 2011/2/10 Réparation réussie 0001 xyz 2011/3/10 Inspection réussie –

Répondre

1

est ici un CTE récursive qui génère table des dernières dates de mois à intervalle commençant par date minimale dans le tableau de réparation et se terminant par jour au maximum.

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

colonne EndDate de tableOfDates doit être ignorée, car elle sert seulement la limite supérieure. Si vous créez une fonction UDF qui renvoie toutes les dates dans un intervalle, omettez endDate dans la liste de sélection ou supprimez-la de CTE et remplacez-la par un paramètre.

Sql Fiddle playground is here.

Questions connexes