Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 用于计算多行之间时间差的T-SQL脚本_Sql Server_Database_Tsql - Fatal编程技术网

Sql server 用于计算多行之间时间差的T-SQL脚本

Sql server 用于计算多行之间时间差的T-SQL脚本,sql-server,database,tsql,Sql Server,Database,Tsql,我有一张这样的桌子: EventDateTime EventName AppID ----------------------------------------- 2014-06-27 22:17:19 GotFocus 1000 2014-06-27 22:17:20 LostFocus 1000 2014-06-27 22:17:22 GotFocus 1005 2014-06-27 22:17:24 LostFocu

我有一张这样的桌子:

EventDateTime           EventName   AppID
-----------------------------------------
2014-06-27 22:17:19     GotFocus    1000
2014-06-27 22:17:20     LostFocus   1000
2014-06-27 22:17:22     GotFocus    1005
2014-06-27 22:17:24     LostFocus   1005
2014-06-27 22:17:27     GotFocus    1000
2014-06-27 22:17:30     LostFocus   1000
2014-06-27 22:17:37     GotFocus    1005
2014-06-27 22:17:40     LostFocus   1005
我需要做的是创建一个T-SQL脚本,计算每个应用程序处于焦点的总持续时间(即每个应用程序所有LostFocus-GotFocus的总和)。因此,对于上表,我应该得到:

Duration    AppID
------------------
4           1000
5           1005

如何实现这一点?

正如xQbert所指出的,这取决于数据的干净程度。假设每个GotFocus都有一个LostFocus,并且LostFocus EventDateTime大于或等于GotFocus EventDateTime,这应该可以工作(fiddle:):

编辑:只是压缩一些不必要的CTE。Fiddle链接已更新。

我喜欢VBlades的答案(我认为它更容易阅读),但这可能会表现得更好一些:

select g.AppId, sum(DATEDIFF(S, g.EventDateTime, l.EventDateTime)) Duration
from Event g
join Event l on g.AppId = l.AppId and g.EventName = 'GotFocus' and l.EventName = 'LostFocus'
where l.EventDateTime = (select MIN(eventDateTime) from Event e3 where e3.AppId = g.AppId and e3.EventName = 'LostFocus' and e3.EventDateTime > g.EventDateTime)
group by g.AppId
order by g.AppId

如果事件顺序始终为GF,则可以使用以下查询:

select y.appid, y.groupnum, datediff(second, y.gotfocus, y.lostfocus) seconds
from (( row_number() over(partition by appid order by eventdatetime) + 1) / 2 as groupnum,
appid, eventname, eventdatetime
from dbo.mytable) x
pivot( max(x.eventdatetime) for x.eventname in ([gotfocus], [lostfocus]) y

注意:我还没有测试过这个解决方案。

我采用了相同的方案,但数据类型不同,下面给出了易于阅读的答案

select kk.bb - jj.aa from
(
    select a , eventname ,sum(c) as aa
    from #tem1
    where eventname = 'login'
    group by a,eventname
) as jj

join 
(
    select a , eventname ,sum(c) as bb
    from #tem1
    where eventname = 'logoff'
    group by a,eventname
) as kk
on jj.a = kk.a

我们能假设每个获得的焦点都有一个丢失的焦点吗?欢迎来到堆栈溢出。请尽快阅读这一页。对于SQL问题,如果您给表起一个名称,它会很有帮助——它会使答案更加一致,如果没有其他问题的话。这是人们经常犯的一个令人惊讶的错误。什么版本的SQL Server?这是给聪明人的,不是给我的。:)干得好。@VBlades,我没那么聪明。有了这个小测试集,我的答案只比你的快2%。感谢VBlades,上面的代码非常棒。只是一个问题。我不能假设我总是在表中记录GotFocus/LostFocus对。应用程序可能会崩溃,因此我可能会记录Focus,但不会丢失Focus。我如何修改上面的代码来“清理”多余的行,而只考虑对呢?@ USER 795331:不用担心。我们能假设它永远是我们没有的最后一个失去焦点吗?如果没有,您希望如何处理丢失的时间?有替代价值吗?是的,我相信有。我想不出哪种情况下我会失去焦点,但却得不到焦点。我们可以假设,我们将始终有GotFocus,可能有也可能没有LostFocus!在只有GotFocus的情况下,我们可以忽略该行,只考虑计算时间的对。@ USER 795331:这里是一个更新的版本。这里有一个小提琴链接:。让我知道它是否适合你。
select kk.bb - jj.aa from
(
    select a , eventname ,sum(c) as aa
    from #tem1
    where eventname = 'login'
    group by a,eventname
) as jj

join 
(
    select a , eventname ,sum(c) as bb
    from #tem1
    where eventname = 'logoff'
    group by a,eventname
) as kk
on jj.a = kk.a