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]);
由此您可以轻松计算工作时间。
修改后的输出:
我正在做一个涉及时间和考勤管理的项目。当我从生物特征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]);
由此您可以轻松计算工作时间。
修改后的输出: