计算事件之间的时间 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
我正在尝试编写查询来计算行之间的时间差,但我失败了。
问题是事件并不总是一个接一个,如果是这种情况,它应该 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