sql查询确定状态?

Posted

技术标签:

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

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

Timestamp (datetime)
Message (varchar(20))

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

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

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

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

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

【问题讨论】:

这个过程可以延续到第二天吗?例如它从晚上 11:59:59 开始,到第二天的某个时间结束 有可能,第一天状态为1,第二天报错。 【参考方案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);

【讨论】:

以上是关于sql查询确定状态?的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询出错

MySQL SQL优化

SQL Server查询卡住了,但没有等待就运行了

按名称查询报表的 SQL 查询,其中许多列按状态计数

SQL Server 查询上次移动的项目

SQL查询以确定是不是有任何与曲目无关的艺术家[关闭]