MS Access SQL 查询时间 In/Out 考勤

MS Access SQL Query for time In/Out attendance

你好,

我正在做一个涉及时间和考勤管理的项目。当我从生物特征reader下载数据时,我得到了以下格式的记录,

午休和工作时间问题

出勤记录Table姓名:dbo_CHECKINOUT 用户 Table 姓名为:dbo_USERINFO

+---------+-----------------------+
| USERID  |       CHECKTIME       |
+---------+-----------------------+
|       5 | 2/16/2020 9:33:08 AM  |
|       2 | 2/16/2020 9:57:48 AM  |
|       3 | 2/16/2020 10:07:31 AM |
|       4 | 2/16/2020 10:36:01 AM |
|       1 | 2/16/2020 11:10:10 AM |
|       3 | 2/16/2020 1:45:15 PM  |
|       5 | 2/16/2020 1:57:46 PM  |
|       2 | 2/16/2020 1:58:19 PM  |
|       3 | 2/16/2020 2:17:46 PM  |
|       2 | 2/16/2020 2:33:39 PM  |
|       5 | 2/16/2020 2:48:26 PM  |
|       1 | 2/16/2020 7:51:57 PM  |
|       3 | 2/16/2020 9:29:20 PM  |
|       5 | 2/16/2020 9:29:25 PM  |
|       2 | 2/16/2020 9:29:29 PM  |
|       4 | 2/16/2020 9:29:46 PM  |
|       5 | 2/17/2020 9:31:47 AM  |
|       3 | 2/17/2020 10:15:13 AM |
|       4 | 2/17/2020 10:28:54 AM |
|       1 | 2/17/2020 11:28:17 AM |
+---------+-----------------------+

我想把上面的记录显示如下,(Log_In、LB_Out、LB_In、Log_Out、WorkTime和LunchBreak是根据'time') 来自 Whosebug 的人帮我做了这个查询

SELECT t.userid, dbo_USERINFO.NAME, DateValue(t.checktime) AS [date], 
Max(IIf(t.counter=0,t.checktime,Null)) AS Log_In, 
Max(IIf(t.counter=1,t.checktime)) AS LB_Out, 
Max(IIf(t.counter=2,t.checktime,Null)) AS LB_In, 
Max(IIf(t.counter=3,t.checktime)) AS Log_Out, 
Format((Log_In-LB_Out)+(LB_In-Log_Out),"hh:nn:ss") AS WorkTime, 
Format(LB_In-LB_Out,"hh:nn:ss") AS LunchBreak
FROM (
    SELECT t.*, 
      (select count(*) from dbo_CHECKINOUT where userid = t.userid and datevalue(checktime) = datevalue(t.checktime) and checktime < t.checktime) AS [counter] FROM dbo_CHECKINOUT AS t)  AS t INNER JOIN dbo_USERINFO ON t.USERID=dbo_USERINFO.USERID
GROUP BY t.userid, dbo_USERINFO.NAME, DateValue(t.checktime);

结果:

userid      date         Log_In        LB_Out        LB_In       Log_Out    WorkTime    LunchBreak
1           16-Feb-20   11:10:10 AM   7:51:57 PM                
1           17-Feb-20   11:28:17 AM                 
2           16-Feb-20   9:57:48 AM    1:58:19 PM    2:33:39 PM  9:29:29 PM  10:56:21     00:35:20
3           16-Feb-20   10:07:31 AM   1:45:15 PM    2:17:46 PM  9:29:20 PM  10:49:18     00:32:31
3           17-Feb-20   10:15:13 AM                 
4           16-Feb-20   10:36:01 AM   9:29:46 PM                
4           17-Feb-20   10:28:54 AM                 
5           16-Feb-20   9:33:08 AM    1:57:46 PM    2:48:26 PM  9:29:25 PM  11:05:37     00:50:40
5           17-Feb-20   9:31:47 AM  

现在的问题是,如您所见,Userid:1 & Userid: 4 没有 LunchBreak。因此,他们的第一个日志将是 Log_In,第二个日志将是 Log_Out,总工作时间将在第一个(Log_In)和第二个(Log_Out)之间。

请帮助我实现这一目标。

这个花哨的查询将 return 午休时间:

SELECT 
    dbo_UserInfo.UserId, 
    DateValue([CheckTime]) AS [Date], 
    TimeValue(Min([CheckTime])) AS LogIn, 

    (Select Max(TimeValue(T.CheckTime)) 
    From dbo_UserInfo As T 
    Where T.UserId = dbo_UserInfo.UserId 
    And DateValue(T.CheckTime) = DateValue(dbo_UserInfo.CheckTime) 
    And T.CheckTime >
        (Select Min(S.CheckTime) 
        From dbo_UserInfo As S 
        Where S.UserId = dbo_UserInfo.UserId 
        And DateValue(S.CheckTime) = DateValue(dbo_UserInfo.CheckTime))) As LogOut,

    (Select Min(TimeValue(T.CheckTime)) 
    From dbo_UserInfo As T 
    Where T.UserId = dbo_UserInfo.UserId 
    And DateValue(T.CheckTime) = DateValue(dbo_UserInfo.CheckTime)
    And T.CheckTime > 
        (Select Min(S.CheckTime) 
        From dbo_UserInfo As S 
        Where S.UserId = dbo_UserInfo.UserId 
        And DateValue(S.CheckTime) = DateValue(dbo_UserInfo.CheckTime))
    And T.CheckTime <
        (Select Max(S.CheckTime) 
        From dbo_UserInfo As S 
        Where S.UserId = dbo_UserInfo.UserId 
        And DateValue(S.CheckTime) = DateValue(dbo_UserInfo.CheckTime))
    Having Count(*) > 1) As LBIn,

    (Select Max(TimeValue(T.CheckTime)) 
    From dbo_UserInfo As T 
    Where T.UserId = dbo_UserInfo.UserId 
    And DateValue(T.CheckTime) = DateValue(dbo_UserInfo.CheckTime) 
    And T.CheckTime > 
        (Select Min(S.CheckTime) 
        From dbo_UserInfo As S 
        Where S.UserId = dbo_UserInfo.UserId 
        And DateValue(S.CheckTime) = DateValue(dbo_UserInfo.CheckTime))
    And T.CheckTime <
        (Select Max(S.CheckTime) 
        From dbo_UserInfo As S 
        Where S.UserId = dbo_UserInfo.UserId 
        And DateValue(S.CheckTime) = DateValue(dbo_UserInfo.CheckTime))
    Having Count(*) > 1) As LBOut
FROM 
    dbo_UserInfo
GROUP BY 
    dbo_UserInfo.UserId, 
    DateValue([CheckTime]);

由此您可以轻松计算工作时间。

修改后的输出: