I'm trying to find out how to calculate difference between multiple rows from one simple query. Here it is:
SELECT [DateTime],EmployeeId,ControlPointID,EventTypeID
FROM [Events]
WHERE Day([DateTime]) = 4
AND Month([DateTime]) = 7
AND Year([DateTime]) = 2017
AND EmployeeId = 451
AND ControlPointID IN ( 3, 6 )
AND EventTypeID IN ( 1, 2 )
ORDER BY [DateTime]
Result:
DateTime EmployeeId ControlPointID EventTypeID
2017-07-04 11:32:10.000 451 6 1
2017-07-04 16:07:00.000 451 3 2
2017-07-04 16:42:50.000 451 6 1
2017-07-04 20:04:10.000 451 3 2
I need to calculate difference between [DateTime]
in minutes.
EventTypeId = 1
means that Employee
enters to the building and EventTypeId=2
means that Employee leaves. I can calculate difference between first Enter Event and last Leave Event. In this case it's 512 minutes. But, i have problem to calculate work time, when someone enters twice and leaves twice. It should be 477 minutes. Calculation should looks like this:
DateDiff = (2017-07-04 16:07:00.000 - 2017-07-04 11:32:10.000) +
(2017-07-04 20:04:10.000 - 2017-07-04 16:42:50.000)
Can you help me figure it out, please ?
答案 0 :(得分:3)
鉴于建筑物入口,可以使用cross apply
select entry.EmployeeId, entry.DateTime, exit.DateTime
from Events entry
cross apply (select top 1 e.DateTime
from Events e
where e.EmployeeId = entry.EmployeeId
and e.DateTime > entry.DateTime
and e.EventTypeId = 2
order by e.DateTime asc
) as exit
where entry.EventTypeId = 1
此时你只需要使用applicable T/SQL function来获得你想要的任何单位的差异(例如,在datediff(minute, entry.DateTime, exit.DateTime)
的分钟内。
要获得所有差异的总和,只需求出差异:
select EmployeeId, sum(mins)
from (
select entry.EmployeeId, entry.DateTime as EntryDateTime, exit.DateTime as ExitDateTime, datediff(minute, EntryDateTime, ExitDateTime) as mins
from Events entry
cross apply (select top 1 e.DateTime
from Events e
where e.EmployeeId = entry.EmployeeId
and e.DateTime > entry.DateTime
and e.EventTypeId = 2
order by e.DateTime asc
) as exit
where entry.EventTypeId = 1
) as input
group by EmployeeId
编辑:添加了总体总和(为了清晰起见,内部带有差异)
答案 1 :(得分:2)
这可以使用LAG
窗口函数来完成,因为2008年我们不需要left join
Row_Number
来查找上一个条目
;WITH cte
AS (SELECT Row_number()OVER(Partition by EmployeeID ORDER BY [DateTime]) rn,*
FROM Yourresult)
SELECT a.EmployeeID,
Sum(Datediff(minute, b.[DateTime], a.[DateTime]))
FROM cte a
LEFT JOIN cte b
ON a.EmployeeID = b.EmployeeID
AND a.rn = b.rn + 1
WHERE a.[EventTypeId] = 2
GROUP BY a.EmployeeID
注意:这认为没有任何错误的打击。就像你的样本数据一样