如何使用sql根据InOutMode计算OverTime的持续时间? [英] How to calculate the duration of an OverTime according to the InOutMode using sql ?
问题描述
我正在尝试计算每位员工的加班时间。
我正在使用日志表:Log_Attendance:
EnrollNumber DateAttendance TimesInOut ModeEvent
1 12-07-2015 12-07-2015 14:00:00 4
1 12-07-2015 12-07-2015 15:00:00 5
1 12-07-2015 12- 07-2015 17:00:00 4
1 12-07-2015 12-07-2015 18:00:00 4
1 12-07-2015 12-07-2015 19:00:00 5
ModeEvent = 4 - > OverTimeOut
ModeEvent = 5 - > OverTimeIn
我需要系统在员工连续行具有相同的ModeEvent时给出NULL(示例第3行:员工有超时但是他没有标记他的OvertimeOut)
我试过这个查询,但它给了我一个错误的值:
SELECT
EnrollNumber,
TimesInOut,
NextDate,
Mode,
DATEDIFF(分钟,TimesInOut,NextDate) as 持续时间
FROM ( SELECT EnrollNumber,
ID,
TimesInOut,
模式,
DateAttendance,
( SELECT MIN(TimesInOut)
FROM Log_Attendance T2
WHERE T2.EnrollNumber = T1.EnrollNumber
AND T2.TimesInOut> T1.TimesInOut
和 T2.Mode<> T1.Mode
) AS NextDate
FROM Log_Attendance T1
其中模式 ( 4 )
) AS T
其中模式中的code-keyword>( 4 , 5 )和 EnrollNumber = 1
请问有什么解决方案吗?
我是否理解你想要NULL,以防有IN标记而不是OUT。
对于这样的查询,例如:
SELECT l1。*, NULL as 超时
FROM Log_Attendance l1
WHERE l1.ModeEvent = 4 - 选择IN事件
AND 5 <> ( SELECT ModeEvent - 搜索相应的out事件
FROM Log_Attendance l2
WHERE l2.EnrollNumber = l1.EnrollNumber
AND l2.TImesInOut =( SELECT MIN(L3.TImesInOut) - 基于下一个时间事件
FROM Log_Attendance l3
WHERE l3.EnrollNumber = l1.EnrollNumber
AND L3。 TImesInOut> l1.TimesInOut))
如果你想让行没有标记但没有cor,你可以反过来反过来在标记中回应并使用UNION组合结果集。
ADDITION
这样的东西?
< pre lang =SQL> SELECT EnrollNumber,
' ' AS desription,
DATEDIFF(小时,l2.TimesInOout,l1.TimesInOut) as time
FROM Log_Attendance l1,
Log_Attendance l2
WHERE l1.ModeEvent = 4
AND l2.ModeEvent = 5
AND l1.EnrollNumber = l2。 EnrollNumber
AND l2.TImesInOut =( SELECT MIN(L3.TImesInOut) - 基于下一个事件的时间
FROM Log_Attendance l3
WHERE l3.EnrollNumber = l1.EnrollNumber
AND L3.TImesInOut> l1.TimesInOut))
UNION ALL
SELECT EnrollNumber,
' 结束时间缺失' AS desription,
NULL as time
FROM Log_Attendance l1
WHERE l1.ModeEvent = 4 - 选择IN事件
AND 5 <> ( SELECT ModeEvent - 搜索相应的out事件
FROM Log_Attendance l2
WHERE l2.EnrollNumber = l1.EnrollNumber
AND l2.TImesInOut =( SELECT MIN(L3.TImesInOut) - 基于下一个时间事件
FROM Log_Attendance l3
WHERE l3.EnrollNumber = l1.EnrollNumber
AND L3。 TImesInOut> l1.TimesInOut))
I'm trying to calculate the duration of the overtime for each employee.
I'm using the Log Table: Log_Attendance:
EnrollNumber DateAttendance TimesInOut ModeEvent
1 12-07-2015 12-07-2015 14:00:00 4
1 12-07-2015 12-07-2015 15:00:00 5
1 12-07-2015 12-07-2015 17:00:00 4
1 12-07-2015 12-07-2015 18:00:00 4
1 12-07-2015 12-07-2015 19:00:00 5
ModeEvent= 4 --> OverTimeOut
ModeEvent= 5 --> OverTimeIn
I need that the system give NULL when the employee has consecutive rows with the same ModeEvent (Example row 3: the employee has an overtimeIN but he hasn't marked his OvertimeOut)
I tried this query but it gives me a wrong values:
SELECT
EnrollNumber,
TimesInOut,
NextDate,
Mode,
DATEDIFF(Minute, TimesInOut, NextDate) as duration
FROM ( SELECT EnrollNumber,
ID,
TimesInOut,
Mode,
DateAttendance,
( SELECT MIN(TimesInOut)
FROM Log_Attendance T2
WHERE T2.EnrollNumber = T1.EnrollNumber
AND T2.TimesInOut > T1.TimesInOut
and T2.Mode <> T1.Mode
) AS NextDate
FROM Log_Attendance T1
where mode in (4)
) AS T
where mode in (4,5) and EnrollNumber=1
Any Solution please ?
Did I understand correctly that you want NULL in case there is an IN mark but not OUT.
For such query something like:
SELECT l1.*, NULL as overtime FROM Log_Attendance l1 WHERE l1.ModeEvent = 4 -- select IN events AND 5 <> (SELECT ModeEvent -- search for the corresponding out event FROM Log_Attendance l2 WHERE l2.EnrollNumber = l1.EnrollNumber AND l2.TImesInOut = (SELECT MIN(L3.TImesInOut) -- based on the next event in time FROM Log_Attendance l3 WHERE l3.EnrollNumber = l1.EnrollNumber AND L3.TImesInOut > l1.TimesInOut))
You can switch the condition vice versa if you want to have the rows with out mark but no corresponding in mark and use UNION to combine the result sets.
ADDITION
Something like this?
SELECT EnrollNumber, '' AS desription, DATEDIFF(hour, l2.TimesInOout, l1.TimesInOut) as time FROM Log_Attendance l1, Log_Attendance l2 WHERE l1.ModeEvent = 4 AND l2.ModeEvent = 5 AND l1.EnrollNumber = l2.EnrollNumber AND l2.TImesInOut = (SELECT MIN(L3.TImesInOut) -- based on the next event in time FROM Log_Attendance l3 WHERE l3.EnrollNumber = l1.EnrollNumber AND L3.TImesInOut > l1.TimesInOut)) UNION ALL SELECT EnrollNumber, 'End time missing' AS desription, NULL as time FROM Log_Attendance l1 WHERE l1.ModeEvent = 4 -- select IN events AND 5 <> (SELECT ModeEvent -- search for the corresponding out event FROM Log_Attendance l2 WHERE l2.EnrollNumber = l1.EnrollNumber AND l2.TImesInOut = (SELECT MIN(L3.TImesInOut) -- based on the next event in time FROM Log_Attendance l3 WHERE l3.EnrollNumber = l1.EnrollNumber AND L3.TImesInOut > l1.TimesInOut))
这篇关于如何使用sql根据InOutMode计算OverTime的持续时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!