【问题标题】:Sql query to determine status?sql查询确定状态?
【发布时间】:2008-09-23 16:23:54
【问题描述】:

我在 MSSQL 数据库中有一个如下所示的表:

Timestamp (datetime)
Message (varchar(20))

每天一次,特定进程会在启动时插入当前时间和消息“已启动”。完成后,它会插入当前时间和“已完成”消息。

什么是一个好的查询或一组语句,给定特定的日期,返回:

  • 0 如果进程从未启动
  • 1 如果进程已启动但未完成
  • 2 如果进程开始和结束

表中还有其他消息,但“Started”和“Finished”是这一进程独有的。

编辑:对于奖励业力,如果数据无效,则引发错误,例如有两个“已启动”消息,或者有一个“已完成”而没有“已启动”。

【问题讨论】:

  • 这个过程可以延续到第二天吗?例如它从晚上 11:59:59 开始,到第二天的某个时间结束
  • 有可能,第一天状态为1,第二天报错。

标签: sql sql-server


【解决方案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

【讨论】:

  • “检测无效条件”代码的第 2 行有错字。应该是'... AndSumFinished = 0 Then...'。不过答案很好。
【解决方案2】:

您缺少唯一标识进程的列。让我们添加一个名为 ProcessID 的 int 列。您还需要另一个表来识别进程。如果您依赖原始表,您将永远不会知道从未启动的进程,因为该进程不会有任何行。

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

【讨论】:

  • 字符串 'Started' 和 'Finished' 对于单个进程是唯一的。我在简化。如果有帮助,请将它们视为“Process1Started”和“Process1Finished”,我只关心流程 1。
【解决方案3】:
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。
【解决方案4】:
select count(*) from process_monitor 
where timestamp > yesterday and timestamp < tomorrow.

或者,您可以使用带最大值的自加入来显示特定日期的最新消息:

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

【讨论】:

    猜你喜欢
    • 2018-09-24
    • 1970-01-01
    • 2018-09-05
    • 2013-07-21
    • 2012-02-18
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    相关资源
    最近更新 更多