我在 Microsoft Access 中编写查询时遇到问题。这就是我的表的样子以及我想从哪里检索数据:
我想编写一个具有以下结果的查询:
正如您在第一个表中看到的那样,员工每天可以签入和签出超过 2 次。当员工第一次签到时,日期/时间应放在第一列“签到”中。当他第二次签到时,日期/时间应放在第二列“签出”中。当他第三次签到时,日期/时间应放在“签到”列中,依此类推。
我从上一个问题中了解到,对于类似的情况,我可以使用子查询和模运算符。但我不知道如何使查询适用于上述问题。
我在 Microsoft Access 中编写查询时遇到问题。这就是我的表的样子以及我想从哪里检索数据:
我想编写一个具有以下结果的查询:
正如您在第一个表中看到的那样,员工每天可以签入和签出超过 2 次。当员工第一次签到时,日期/时间应放在第一列“签到”中。当他第二次签到时,日期/时间应放在第二列“签出”中。当他第三次签到时,日期/时间应放在“签到”列中,依此类推。
我从上一个问题中了解到,对于类似的情况,我可以使用子查询和模运算符。但我不知道如何使查询适用于上述问题。
让我们从上一个问题的答案开始,然后从那里开始工作。
此查询定义它是签入还是签出。我们称之为 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