У меня есть таблица в базе данных MSSQL, которая выглядит так:
Timestamp (datetime)
Message (varchar(20))
Раз в день конкретный процесс вставляет текущее время и сообщение «Запущено» при запуске. По завершении вставляет текущее время и сообщение «Готово».
Что такое хороший запрос или набор инструкций, которые, учитывая конкретную дату, возвращают:
В таблице есть и другие сообщения, но «Начато» и «Завершено» уникальны для этого процесса.
Обновлено: для бонусной кармы выдайте ошибку, если данные недействительны, например, есть два сообщения «Начато» или «Завершено» без «Начато».
Возможно, это будет статус 1 для первого дня и ошибка на следующий день.


Select Count(Message) As Status
From Process_monitor
Where TimeStamp >= '20080923'
And TimeStamp < '20080924'
And (Message = 'Started' or Message = 'Finished')
Вы можете немного изменить это, чтобы обнаруживать недопустимые условия, такие как несколько запусков, завершение, запуск без завершения и т. д.
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
Опечатка во второй строке кода обнаружения недопустимых условий. Должно быть '... AndSumFinished = 0 Then ...'. Но хороший ответ.
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
Отредактировано: старый код позволял возвращать случай «Завершено перед запуском» 2.
Ваш случай обработки ошибок вернет -1, если в таблице есть другие сообщения.
Работает по назначению! (если вы хотите отфильтровать, конструкция для этого - предложение where).
Да, я просто указываю на то, что в таблице допустимо наличие других сообщений, поэтому возвращать -1, когда они есть, на самом деле неверно.
select count(*) from process_monitor
where timestamp > yesterday and timestamp < tomorrow.
В качестве альтернативы вы можете использовать самостоятельное соединение с максимумом, чтобы показать самое новое сообщение за определенный день:
select * from process_monitor where
timestamp=(select max(timestamp) where timestamp<next_day);
Вам не хватает столбца, который однозначно идентифицирует процесс. Давайте добавим столбец типа int с именем ProcessID. Вам также понадобится другая таблица для идентификации процессов. Если бы вы полагались на свою исходную таблицу, вы бы никогда не узнали о процессах, которые никогда не запускались, потому что для этого процесса не было бы никакой строки.
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
Строки «Начато» и «Завершено» уникальны для одного процесса. Я упрощал. Если это поможет, подумайте о них как о «Process1Started» и «Process1Finished», где меня интересует только процесс 1.
может ли процесс перенести на следующий день? например Он начинается в 23:59:59 и заканчивается на следующий день.