2008-09-23 5 views
3

J'ai une table dans une base de données MSSQL qui ressemble à ceci:Requête Sql pour déterminer le statut?

Timestamp (datetime) 
Message (varchar(20)) 

Une fois par jour, un processus particulier insère l'heure et le message « Démarrage » quand il commence. Quand il est terminé, il insère l'heure actuelle et le message 'Terminé'.

Qu'est-ce qu'une bonne requête ou un ensemble de déclarations qui, étant donné une date donnée, retourne:

  • 0 si le processus n'a jamais commencé
  • 1 si le processus a commencé, mais n'a pas fini
  • 2 si le processus a démarré et s'est terminé

Il existe d'autres messages dans la table, mais 'Started' et 'Terminé' sont uniques à ce processus.

EDIT: Pour le karma bonus, déclenchez une erreur si les données ne sont pas valides, par exemple s'il y a deux messages 'Started' ou s'il y a un 'Finished' sans 'Started'.

+0

Est-ce que le processus peut passer au jour suivant? par exemple. Il commence à 23:59:59 PM et se termine parfois le jour suivant –

+0

Son possible, ce serait le statut 1 pour le premier jour et une erreur le jour suivant. –

Répondre

2
Select Count(Message) As Status 
From Process_monitor 
Where TimeStamp >= '20080923' 
     And TimeStamp < '20080924' 
     And (Message = 'Started' or Message = 'Finished') 

Vous pouvez modifier cette légèrement pour détecter des conditions non valides, comme plusieurs départs, se termine, commence sans finition, etc ...

Select Case When SumStarted = 0 And SumFinished = 0 Then 'Not Started' 
      When SumStarted = 1 And SumFinished = 0 Then 'Started' 
      When SumStarted = 1 And SumFinished = 1 Then 'Finished' 
      When SumStarted > 1 Then 'Multiple Starts' 
      When SumFinished > 1 Then 'Multiple Finish' 
      When SumFinished > 0 And SumStarted = 0 Then 'Finish Without Start' 
      End As StatusMessage 
From (
      Select Sum(Case When Message = 'Started' Then 1 Else 0 End) As SumStarted, 
       Sum(Case When Message = 'Finished' Then 1 Else 0 End) As SumFinished 
      From Process_monitor 
      Where TimeStamp >= '20080923' 
       And TimeStamp < '20080924' 
       And (Message = 'Started' or Message = 'Finished') 
     ) As AliasName 
+0

Il y a une faute de frappe dans la ligne 2 du code 'détecter les conditions invalides'. Devrait être '... AndSumFinished = 0 Then ...'. Bonne réponse cependant. –

0
DECLARE @TargetDate datetime 
SET @TargetDate = '2008-01-01' 

DECLARE @Messages varchar(max) 

SET @Messages = '' 

SELECT @Messages = @Messages + '|' + Message 
FROM process_monitor 
WHERE @TargetDate <= Timestamp and Timestamp < DateAdd(dd, 1, @TargetDate) 
    and Message in ('Finished', 'Started') 
ORDER BY Timestamp desc 

SELECT CASE 
    WHEN @Messages = '|Finished|Started' THEN 2 
    WHEN @Messages = '|Started' THEN 1 
    WHEN @Messages = '' THEN 0 
    ELSE -1 
END 
+0

Édition: L'ancien code a permis de renvoyer le cas "Terminé avant le démarrage". –

+0

Votre cas de gestion des erreurs renverra -1 s'il y a d'autres messages dans la table. –

+0

Travailler comme prévu! (Si vous voulez filtrer, la construction à faire est une clause where). –

-1
select count(*) from process_monitor 
where timestamp > yesterday and timestamp < tomorrow. 

Alternativement, vous pouvez utiliser une auto-jointure avec un maximum pour afficher le message le plus récent pour un jour particulier:

select * from process_monitor where 
timestamp=(select max(timestamp) where timestamp<next_day); 
0

Il vous manque une colonne qui identifie le processus de manière unique. Ajoutons une colonne int appelée ProcessID. Vous aurez également besoin d'une autre table pour identifier les processus. Si vous vous reposiez sur votre table d'origine, vous ne seriez jamais au courant des processus qui n'ont jamais démarré car il n'y aurait pas de ligne pour ce processus.

select 
    ProcessID, 
    ProcessName, 

    CASE 
    WHEN 
     (Select 
      COUNT(*) 
     from 
      ProcessActivity 
     where 
      ProcessActivity.processid = Processes.processid 
      and Message = 'STARTED') = 1 

     And 
     (Select 
      COUNT(*) 
     from 
      ProcessActivity 
     where 
      ProcessActivity.processid = Processes.processid 
      and Message = 'FINISHED') = 0 
    THEN 1 

    WHEN 
     (Select 
      COUNT(*) 
     from 
      ProcessActivity 
     where 
      ProcessActivity.processid = Processes.processid 
      and Message = 'STARTED') = 1 
     And 
     (Select 
      COUNT(*) 
     from 
      ProcessActivity 
     where 
      ProcessActivity.processid = Processes.processid 
      and Message = 'FINISHED') = 1 
THEN 2 
    ELSE 0 

END as Status 

From 
    Processes 
+0

Les chaînes 'Started' et 'Finished' sont uniques à un seul processus. Je simplifiais. Si cela vous aide, considérez-les comme 'Process1Started' et 'Process1Finished', où je me soucie seulement du Processus 1. –

Questions connexes