用于计算应用程序正常运行时间的SQL查询
我有一个应用程序,它将连接和断开等信息记录在同一个表中。我想尝试计算应用程序的总正常运行时间 桌子的结构是这样的用于计算应用程序正常运行时间的SQL查询,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个应用程序,它将连接和断开等信息记录在同一个表中。我想尝试计算应用程序的总正常运行时间 桌子的结构是这样的 status time connect 2015-09-28 12:05:45.783 disconnect 2015-09-28 12:09:45.783 connect 2015-09-28 12:35:15.783 disconnect 2015-09-28 14:45:35.783 /* status time connect 2015
status time
connect 2015-09-28 12:05:45.783
disconnect 2015-09-28 12:09:45.783
connect 2015-09-28 12:35:15.783
disconnect 2015-09-28 14:45:35.783
/*
status time
connect 2015-09-28 12:05:45.783
disconnect 2015-09-28 12:09:45.783
connect 2015-09-28 12:35:15.783
disconnect 2015-09-28 14:45:35.783
*/
declare @0 datetime;
set @0 = '2015-09-28 12:00:0.000'
declare @1 datetime;
set @1 = '2015-09-28 12:05:45.783'
declare @2 datetime;
set @2 = '2015-09-28 12:09:45.783'
declare @3 datetime;
set @3 = '2015-09-28 12:35:45.783'
declare @4 datetime;
set @4 = '2015-09-28 14:45:45.783'
select DATEDIFF(MS, @1, @3)
select DATEDIFF(MS, @2, @4)
编辑:
我将如何编写查询来计算此值?我试着用总时间,像这样的东西
status time
connect 2015-09-28 12:05:45.783
disconnect 2015-09-28 12:09:45.783
connect 2015-09-28 12:35:15.783
disconnect 2015-09-28 14:45:35.783
/*
status time
connect 2015-09-28 12:05:45.783
disconnect 2015-09-28 12:09:45.783
connect 2015-09-28 12:35:15.783
disconnect 2015-09-28 14:45:35.783
*/
declare @0 datetime;
set @0 = '2015-09-28 12:00:0.000'
declare @1 datetime;
set @1 = '2015-09-28 12:05:45.783'
declare @2 datetime;
set @2 = '2015-09-28 12:09:45.783'
declare @3 datetime;
set @3 = '2015-09-28 12:35:45.783'
declare @4 datetime;
set @4 = '2015-09-28 14:45:45.783'
select DATEDIFF(MS, @1, @3)
select DATEDIFF(MS, @2, @4)
这是一个快速且肮脏的方法,但它可以工作-使用通用表表达式(cte):
注意:对于我的示例,我将列名更改为statustext和logtime
status
和time
是SQL关键字,不应用作列名 使用公共表表达式,可以将状态历史记录排列到视图中,每个记录都有开始时间和结束时间,如下所示:
我使用了coalesce(t2.ts,getdate())
来获取范围内最后一条记录的当前日期时间
如果要查找每个状态保持的时间,请使用datediff()
函数,如下所示:
如果你想要总的上下时间,那只是数学和格式:
这个问题似乎被抛弃了。然而,为了帮助未来读者解决类似问题,以下是如何解决的方法: 该表包含交替记录:连接、断开连接、连接、断开连接等。我们可以使用
LAG
查看前一行。这样做,我们只需要将断开连接的记录与其以前记录的时间(当然是其连接时间)进行比较
只是,重要的是,首先获取以前的时间,然后过滤“断开连接”。如果我们直接使用进行过滤,其中status='disconnect
,那么LAG
当然会给我们上一条disconnect记录的时间。因此,我们首先编写内部滞后查询,然后使用它过滤外部所需的记录
select sum(time_used) as total_seconds
from
(
select
datediff(second, log_time, lag(log_time) over (order by log_time)) as time_used,
status
from connection_logs
) times_used
where status = 'disconnect';
SQL fiddle:
我们通常还应该考虑丢失连接或断开连接记录的情况,因此我们将有两个连续的连接或断开连接。一种解决方案是忽略缺少合作伙伴的记录,因此我们将查看lag(status)
,只有在该状态确实为“connect”时才使用它:
select sum(time_used) as total_seconds
from
(
select
datediff(second, log_time, lag(log_time) over (order by log_time)) as time_used,
status,
lag(status) over (order by log_time) as previous_status
from connection_logs
) times_used
where status = 'disconnect'
and previous_status = 'connect';
SQL fiddle您当前的查询是什么,您遇到了什么错误?您似乎还没有对这个问题考虑太多。第一步是为每个连接找到匹配的断开连接,对吗?然后考虑在数据不一致(两个连接或两个断开连接紧随其后)的情况下该怎么办。您不应该查看1&2和3&4之间的日期差吗?为什么是1-3和2-4?跟踪选项卡问题:每次只有4个条目吗?输出到哪里去了?请回答您的问题,插入所有相关信息。以下类似问题可能对您有用-编辑:我做了更改,HH:MM:SS中的显示现在包括天。另一种选择是不让分钟变成小时(60分钟)或小时变成天(24小时)。
select sum(time_used) as total_seconds
from
(
select
datediff(second, log_time, lag(log_time) over (order by log_time)) as time_used,
status
from connection_logs
) times_used
where status = 'disconnect';
select sum(time_used) as total_seconds
from
(
select
datediff(second, log_time, lag(log_time) over (order by log_time)) as time_used,
status,
lag(status) over (order by log_time) as previous_status
from connection_logs
) times_used
where status = 'disconnect'
and previous_status = 'connect';