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