如何计算每个会话的员工总工作时间
How to calculate Total working hours of employee by each session
我需要显示一天中每个会话的员工登录和注销时间,并计算总工作时间。如果员工登录和注销多次,则应显示每次会话和总数。
我的 table 看起来像这样
Id
EmpId
LocationId
LogDate
AccessType
OutType
1
4545_1
4545
2022-05-25 16:27:41.217
1
NULL
2
4545_1
4545
2022-05-25 17:27:26.673
2
1
4
4545_1
4545
2022-05-25 17:31:30.333
1
NULL
5
4545_1
4545
2022-05-25 19:31:38.973
2
1
6
1212_8
1212
2022-05-26 10:21:38.973
1
NULL
6
1212_8
1212
2022-05-26 12:21:38.973
2
2
这里
访问类型 1=IN 2=OUT
OutType 1=注销 2=会话退出
我想要这样的输出
EmpId
LocationId
SessionStart
SessionEnd
Hours
4545_1
4545
2022-05-25 16:27:41.217
2022-05-25 17:27:26.673
1:00
4545_1
4545
2022-05-25 17:31:30.333
2022-05-25 19:31:38.973
2:00
1212_8
1212
2022-05-26 10:21:38.973
2022-05-26 12:21:38.973
2:00
这是我试过的
select[EmpId],
[LocationId],
ShiftDate,
SessionStartTime,
SessionEndTime
, Total_Time = right(concat('0', Total_Time / 3600), 2) + ':' + right(concat('0', Total_Time % 3600 / 60), 2)
from (
select
[EmpId],[LocationId], ShiftDate = cast(min(LogDate) as date)
, SessionStartTime = min(LogDate)
, SessionEndTime = max(LogDate)
, Total_Time = sum(ss)
from (
select
*, ss = datediff(ss, LogDate, lead(LogDate) over (partition by [EmpId], grp order by LogDate))
from (
select
*, grp = sum(diff) over (partition by [EmpId] order by LogDate)
from (
select
*, diff = iif(datediff(mi, lag(LogDate) over (partition by [EmpId] order by LogDate), LogDate) > 300 and [AccessType] = 1, 1, 0)
from
[tblEmployeeAttendance] where cast(LogDate as date) >= '2022-05-25' and cast(LogDate as date) <= '2022-05-26'
) t
) t
) t
group by [EmpId],[LocationId], grp) t
我得到了这样的结果
EmpId
LocationId
SessionStart
SessionEnd
Hours
4545_1
4545
2022-05-25 16:27:41.217
2022-05-25 19:31:38.973
3:00
1212_8
1212
2022-05-26 10:21:38.973
2022-05-26 12:21:38.973
2:00
这里的问题是我在一行中只获得一天的最小登录和最大注销。但是我需要用户当天的每个登录和注销会话以及每个会话的总数。
我请人帮忙。
您可以使用外部应用来完成此操作。
不知道OutType有什么用,和AccessType有什么区别。您没有解释那个或任何其他逻辑,所以我只是假设它应该适用于 AccessType。
如果不是这种情况,您可以轻松调整下面子查询中的逻辑。
select e.EmpId,
e.LocationID,
e.logdate as SessionStart,
d.logdate as SessionEnd,
datediff(hour, e.logdate, d.logdate) as Hours
from emp e
outer apply ( select top 1 emp.logdate
from emp
where emp.empid = e.empid
and emp.accesstype = 2
and emp.logdate > e.logdate
order by emp.logdate
) d
where e.accesstype = 1
查看DBFiddle这里
结果
EmpId
LocationID
SessionStart
SessionEnd
Hours
4545_1
4545
2022-05-25 16:27:41.217
2022-05-25 17:27:26.673
1
4545_1
4545
2022-05-25 17:31:30.333
2022-05-25 19:31:38.973
2
1212_8
1212
2022-05-26 10:21:38.973
2022-05-26 12:21:38.973
2
我需要显示一天中每个会话的员工登录和注销时间,并计算总工作时间。如果员工登录和注销多次,则应显示每次会话和总数。
我的 table 看起来像这样
Id | EmpId | LocationId | LogDate | AccessType | OutType |
---|---|---|---|---|---|
1 | 4545_1 | 4545 | 2022-05-25 16:27:41.217 | 1 | NULL |
2 | 4545_1 | 4545 | 2022-05-25 17:27:26.673 | 2 | 1 |
4 | 4545_1 | 4545 | 2022-05-25 17:31:30.333 | 1 | NULL |
5 | 4545_1 | 4545 | 2022-05-25 19:31:38.973 | 2 | 1 |
6 | 1212_8 | 1212 | 2022-05-26 10:21:38.973 | 1 | NULL |
6 | 1212_8 | 1212 | 2022-05-26 12:21:38.973 | 2 | 2 |
这里 访问类型 1=IN 2=OUT OutType 1=注销 2=会话退出
我想要这样的输出
EmpId | LocationId | SessionStart | SessionEnd | Hours |
---|---|---|---|---|
4545_1 | 4545 | 2022-05-25 16:27:41.217 | 2022-05-25 17:27:26.673 | 1:00 |
4545_1 | 4545 | 2022-05-25 17:31:30.333 | 2022-05-25 19:31:38.973 | 2:00 |
1212_8 | 1212 | 2022-05-26 10:21:38.973 | 2022-05-26 12:21:38.973 | 2:00 |
这是我试过的
select[EmpId],
[LocationId],
ShiftDate,
SessionStartTime,
SessionEndTime
, Total_Time = right(concat('0', Total_Time / 3600), 2) + ':' + right(concat('0', Total_Time % 3600 / 60), 2)
from (
select
[EmpId],[LocationId], ShiftDate = cast(min(LogDate) as date)
, SessionStartTime = min(LogDate)
, SessionEndTime = max(LogDate)
, Total_Time = sum(ss)
from (
select
*, ss = datediff(ss, LogDate, lead(LogDate) over (partition by [EmpId], grp order by LogDate))
from (
select
*, grp = sum(diff) over (partition by [EmpId] order by LogDate)
from (
select
*, diff = iif(datediff(mi, lag(LogDate) over (partition by [EmpId] order by LogDate), LogDate) > 300 and [AccessType] = 1, 1, 0)
from
[tblEmployeeAttendance] where cast(LogDate as date) >= '2022-05-25' and cast(LogDate as date) <= '2022-05-26'
) t
) t
) t
group by [EmpId],[LocationId], grp) t
我得到了这样的结果
EmpId | LocationId | SessionStart | SessionEnd | Hours |
---|---|---|---|---|
4545_1 | 4545 | 2022-05-25 16:27:41.217 | 2022-05-25 19:31:38.973 | 3:00 |
1212_8 | 1212 | 2022-05-26 10:21:38.973 | 2022-05-26 12:21:38.973 | 2:00 |
这里的问题是我在一行中只获得一天的最小登录和最大注销。但是我需要用户当天的每个登录和注销会话以及每个会话的总数。
我请人帮忙。
您可以使用外部应用来完成此操作。
不知道OutType有什么用,和AccessType有什么区别。您没有解释那个或任何其他逻辑,所以我只是假设它应该适用于 AccessType。
如果不是这种情况,您可以轻松调整下面子查询中的逻辑。
select e.EmpId,
e.LocationID,
e.logdate as SessionStart,
d.logdate as SessionEnd,
datediff(hour, e.logdate, d.logdate) as Hours
from emp e
outer apply ( select top 1 emp.logdate
from emp
where emp.empid = e.empid
and emp.accesstype = 2
and emp.logdate > e.logdate
order by emp.logdate
) d
where e.accesstype = 1
查看DBFiddle这里
结果
EmpId | LocationID | SessionStart | SessionEnd | Hours |
---|---|---|---|---|
4545_1 | 4545 | 2022-05-25 16:27:41.217 | 2022-05-25 17:27:26.673 | 1 |
4545_1 | 4545 | 2022-05-25 17:31:30.333 | 2022-05-25 19:31:38.973 | 2 |
1212_8 | 1212 | 2022-05-26 10:21:38.973 | 2022-05-26 12:21:38.973 | 2 |