计算事件之间的时间 SQL 服务器

Calculate time between events SQL Server

我正在尝试编写查询来计算行之间的时间差,但我失败了。

问题是事件并不总是一个接一个,如果是这种情况,它应该 return NULL 值或完全跳过它。

示例table

Time ComputerName RenderedDescription EventDisplayNumber
2022-05-19 14:12:58.400 COMP16 The Event log service was started. 6005
2022-05-19 13:52:46.360 COMP16 The Event log service was stopped. 6006
2022-05-19 13:15:47.417 COMP16 The Event log service was started. 6005
2022-05-08 08:26:11.777 COMP16 The Event log service was started. 6005
2022-05-08 07:30:11.030 COMP16 The Event log service was stopped. 6006
2022-05-01 08:22:37.553 COMP16 The Event log service was started. 6005
2022-05-01 07:30:08.057 COMP16 The Event log service was stopped. 6006
2022-04-24 08:20:55.190 COMP16 The Event log service was started. 6005
2022-04-24 07:30:07.143 COMP16 The Event log service was stopped. 6006

以及我想要得到的结果

ComputerName Event Stopped Event Started DifferenceMinutes
COMP16 2022-04-24 07:30:07.143 2022-04-24 08:20:55.190 50
COMP16 2022-05-01 07:30:08.057 2022-05-01 08:22:37.553 52
COMP16 2022-05-08 07:30:11.030 2022-05-08 08:26:11.777 56
COMP16 NULL 2022-05-19 13:15:47.417 NULL
COMP16 2022-05-19 13:52:46.360 2022-05-19 14:12:58.400 20

这将适用于您的示例数据:

with Data as (
    select *,
        case when RenderedDescription like '%started%' then 'S'
             when RenderedDescription like '%stopped%' then 'E' end as Code,
        count(case when RenderedDescription like '%started%' then 1 end)
            over (partition by ComputerName order by "Time" desc) as Grp
    from EventLog
)
select
    ComputerName,
    max(case when Code = 'E' then "Time" end) as EventStopped,
    min(case when Code = 'S' then "Time" end) as EventStarted,
    datediff(second, 
        max(case when Code = 'E' then "Time" end),
        min(case when Code = 'S' then "Time" end)
    ) / 60 as DifferenceMinutes

from Data
group by ComputerName, Grp
order by ComputerName, EventStarted;

如果您可以连续启动和停止,那么试试这个:

with Data as (
    select *,
        case when RenderedDescription like '%started%' then 'S'
             when RenderedDescription like '%stopped%'  then 'E' end as Code,
        lag(
            case when RenderedDescription like '%started%' then 'S'
                 when RenderedDescription like '%stopped%'  then 'E' end
        ) over (partition by ComputerName order by "Time") as LastCode
    from EventLog
), Grouped as (
    select *,
        count(case when LastCode = 'E' and Code = 'S' then null else 1 end)
            over (partition by ComputerName order by "Time") as Grp
    from Data
)
select
    ComputerName,
    max(case when Code = 'E' then "Time" end) as EventStopped,
    min(case when Code = 'S' then "Time" end) as EventStarted,
    datediff(second, 
        max(case when Code = 'E' then "Time" end),
        min(case when Code = 'S' then "Time" end)
    ) / 60 as DifferenceMinutes
from Grouped
group by ComputerName, Grp
order by ComputerName, EventStarted;

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d7bd556c49cbca84d025bcd1eedc9771