从日志表中获取使用app的持续时间

时间:2012-12-10 19:10:54

标签: sql sql-server stored-procedures

我有一张桌子,我正在记录登录/注销。架构和示例数据:http://sqlfiddle.com/#!2/e1b35/1

我需要创建存储过程,该存储过程将为用户和日期打印(登出 - 登录)时间的总和(在日期使用用户的应用程序的持续时间)。在列类型中,I表示登录和O注销。

输入参数:@ username,@ date。输出:时间。

2 个答案:

答案 0 :(得分:1)

您需要识别彼此相关的所有登录组。我这样做的方法是找到与登录相关的注销。您正在处理日志数据,因此如果有多个登录没有注销,请不要感到惊讶。

select l.*,
       (select min(l2.time) from logs l2 where l2.username = l.username and l2.type = 'O' and l2.time > l.time
       ) as logoutTime
from logs l
where l.type = 'I'

现在,您可以将用户名和LogoutTime用作聚合对,以获得您想要的内容:

select username, logoutTime, min(time) as StartTime, logouttime as EndTime,
       datediff(s, min(time), logoutTime) as TimeInSeconds
from (select l.*,
             (select min(l2.time) from logs l2 where l2.username = l.username and l2.type = 'O' and l2.time > l.time
             ) as logoutTime
      from logs l
      where l.type = 'I'
     ) l
group by username, logoutTime

请注意,您将SQL Server指定为标记,但SQL Fiddle适用于MySQL;日期函数在数据库之间往往不同。

而且,如果您使用的是SQL Server 2012,则有一种更简单的方法。如果是这种情况,您应该指定。

答案 1 :(得分:0)

这是Gordon Linoff的解决方案,经过修改,因此它不包含最外层的聚合,并使用更清晰的别名,IMO

select username,time_in,time_out_min,
       datediff(s, time_in, time_out_min) as TimeInSeconds
from (
select i.username, i.time as time_in,
       (select min(o.time) as min_time_out
        from logs o 
        where o.username = i.username and 
        o.type = 'O' and 
        o.time > i.time
       ) as time_out_min
from logs i
where i.type = 'I'
  ) d;