如何使用sql根据InOutMode计算OverTime的持续时间? [英] How to calculate the duration of an OverTime according to the InOutMode using sql ?

查看:141
本文介绍了如何使用sql根据InOutMode计算OverTime的持续时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试计算每位员工的加班时间。

我正在使用日志表: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆