0

我在 Microsoft Access 中编写查询时遇到问题。这就是我的表的样子以及我想从哪里检索数据:

在此处输入图像描述

我想编写一个具有以下结果的查询:

在此处输入图像描述

正如您在第一个表中看到的那样,员工每天可以签入和签出超过 2 次。当员工第一次签到时,日期/时间应放在第一列“签到”中。当他第二次签到时,日期/时间应放在第二列“签出”中。当他第三次签到时,日期/时间应放在“签到”列中,依此类推。

我从上一个问题中了解到,对于类似的情况,我可以使用子查询和模运算符。但我不知道如何使查询适用于上述问题。

4

1 回答 1

1

让我们从上一个问题的答案开始,然后从那里开始工作。

此查询定义它是签入还是签出。我们称之为 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
于 2018-03-12T13:21:44.423 回答