【问题标题】:MS Access SQL Query for time In/Out attendanceMS Access SQL 查询考勤时间
【发布时间】:2020-06-01 02:47:32
【问题描述】:
你好,

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

午休和工作时间问题

考勤记录表名称:dbo_CHECKINOUT 用户表名: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') StackOverFlow 的某个人帮助我进行了这个查询

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 没有午餐时间。所以他们的第一个日志是 Log_In,第二个日志是 Log_Out,总工作时间在 1st(Log_In) 和 2nd(Log_Out) 之间。

请帮助我实现这一点。

【问题讨论】:

标签: sql database vba ms-access time-and-attendance


【解决方案1】:

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

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]);

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

修改后的输出:

【讨论】:

  • 感谢您的询问。我复制您的查询并尝试运行它,它会询问我一些参数值。我该怎么办?
  • 我的用户表和日志表是不同的,dbo_CHECKINOUT 用于日志,dbo_USERINFO 用于员工
  • 调整表和字段名以匹配你的,它会运行。
  • 嗨,@Gustav,它正在工作。但是,我还有一些问题。一个人还没有注销,他/她的注销字段仍然是登录时间
  • 有没有其他方法可以让该字段留空直到注销?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多