我在使用Microsoft Access编写查询时遇到了麻烦。 这就是我的表格的样子以及我想从中检索数据的位置:
我想编写一个具有以下结果的查询:
正如您在第一张表中所见,员工每天可以检查IN和OUT超过2次。当员工第一次登记时,日期/时间应放在第一个列“CheckIn”中。当他第二次登记时,日期/时间应放在第二栏“CheckOut”中。当他第3次登记时,日期/时间应放在“CheckIn”栏中,依此类推。
我从上一个问题中了解到,我可以使用子查询和模数运算符来处理类似的情况。但我无法弄清楚我如何使查询适用于上述问题。
答案 0 :(得分:0)
让我们从上一个问题的答案开始,然后从那里开始工作。
此查询定义是签入还是签出。我们称之为qryCheckInOut
SELECT EmployeeID,
timeInOut,
IIF(
(SELECT COUNT(*)
FROM MyTable s
WHERE s.EmployeeID = m.EmployeeID
AND s.timeInOut <= m.timeInOut
AND s.timeInOut >= INT(m.timeInOut)) Mod 2 = 1, "I", "O") As OriginType
FROM MyTable m
然后,我们可以从该查询中获取签到,并使用子查询来获取结账。
我们使用条件确保结帐时间与登记时间相同,并使用Min
汇总确保下次(最短时间) )。
SELECT q.EmployeeID,
q.TimeInOut As TimeIn,
(SELECT Min(s.TimeInOut)
FROM qryCheckInOut s
WHERE s.EmployeeID = q.EmployeeId
AND s.TimeInOut > q.TimeInOut
AND s.TimeInOut <= Int(q.TimeInOut) + 1) As TimeOut
FROM qryCheckInOut q
WHERE q.OriginType = 'I'
请注意,在第二个查询的子查询中,您不需要检查它是否签入或签出,因为最高时间高于同一天的签入总是退房。
如果您想在单个查询中执行此操作,可以使用以下查询。但是,调试将会非常困难
SELECT m.EmployeeID,
m.TimeInOut As TimeIn,
(SELECT Min(s.TimeInOut)
FROM MyTable s
WHERE s.EmployeeID = m.EmployeeId
AND s.TimeInOut > m.TimeInOut
AND s.TimeInOut <= Int(m.TimeInOut) + 1) As TimeOut
FROM MyTable m
WHERE
(SELECT COUNT(*)
FROM MyTable s
WHERE s.EmployeeID = m.EmployeeID
AND s.timeInOut <= m.timeInOut
AND s.timeInOut >= INT(m.timeInOut)) Mod 2 = 1