我有一个看起来像这样的表:
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
我怎样才能做到这一点?
答案 0 :(得分:1)
正如xQbert指出的那样,取决于你的数据是多么干净。假设每个GotFocus都有一个LostFocus,并且LostFocus EventDateTime大于或等于GotFocus EventDateTime,这应该可以工作(小提琴:http://sqlfiddle.com/#!3/f36a4/14):
WITH cteGotFocus
AS
(
SELECT AppID,
ROW_NUMBER() OVER(PARTITION BY AppID ORDER BY EventDateTime) AS RID,
EventDateTime
FROM Table1
WHERE EventName = 'GotFocus'
),
cteLostFocus
AS
(
SELECT AppID,
ROW_NUMBER() OVER(PARTITION BY AppID ORDER BY EventDateTime) AS RID,
EventDateTime
FROM Table1
WHERE EventName = 'LostFocus'
)
SELECT SUM(DATEDIFF(s, gf.EventDateTime, lf.EventDateTime)) AS Duration,
gf.AppID
FROM cteGotFocus gf INNER JOIN cteLostFocus lf
ON gf.AppID = lf.AppID AND
gf.RID = lf.RID
GROUP BY gf.AppID
ORDER BY gf.AppID;
编辑:只是缩减了一些不必要的CTE。小提琴链接已更新。
答案 1 :(得分:0)
我喜欢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
答案 2 :(得分:0)
如果事件序列始终是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
注意:我没有测试过这个解决方案。
答案 3 :(得分:-1)
我采用相同的方案,但有不同的数据类型,答案很容易阅读
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