计算一个工作日的时间分布在2个不同的日子 - 访问SQL

时间:2016-09-05 12:37:03

标签: sql datetime ms-access

对于一家公司,我正在计算每位员工的工作时间。计算由他们进出时钟完成。

因此它按如下方式插入数据库中:

--Record

    Relation: 1101
    Clock Date and time: 2016-09-05 14:00
    Type: Clock IN 
    Worked hours: 0 (always 0 on IN)

--Record

    Relation: 1101
    Clock Date and time: 2016-09-05 16:00
    Type: Clock OUT
    Worked hours: 2 (= clocked out datetime minus clocked in datetime)

这最近一直有效。该公司已经扩展,他们现在在晚上(1:00)工作,直到+/- 1个时钟,而他们过去在工作时间(22:00)工作到最多10个钟。

在我的Access数据库中,我显示一个表单,显示一整天的总工作时间,而不是每个时钟进出的工作时间。我根据特定员工的最小(日期)和最大(日期)计算这些小时数。但是,因为它们现在有时会在晚上输出OUT,所以记录会搞砸。

例如:员工A于2016-09-05 17:00开始计时,并于2016-09-06至1:00工作。 MIN得到17:00时间,但MAX现在也得到17:00时间(因为MIN / MAX是基于日期而且时钟是在第二天......)。因此,Form正在检索不正确的值。

有一种简单的方法可以围绕这个构建一些东西吗?

查询如下所示:

SELECT EmpoyeeID
     , EmployeeName
     , EmployeeAge
     , DatePart("yyyy", [ClockDateTime]) AS year
     , DatePart("m", [ClockDateTime]) AS month
     , DatePart("d", [ClockDateTime]) AS day
     , Min(ClockDateTime) AS StartTime
     , Max(ClockDateTime) AS EndTime
     , DateDiff("n", Min([ClockDateTime]), Max([ClockDateTime]))/60 AS TotalWorkedToday
  FROM HourRegistration
 GROUP 
    BY EmpoyeeID
     , EmployeeName
     , EmployeeAge
     , DatePart("yyyy", [ClockDateTime])
     , DatePart("m", [ClockDateTime])
     , DatePart("d", [ClockDateTime]);

2 个答案:

答案 0 :(得分:1)

从开始时间和结束时间中删除2小时应该可以解决问题 按[ClockDateTime]

替换查询中的每[ClockDateTime] - #1/1/1900 2:0:0#次出现

只要工作日在凌晨3点至次日凌晨2点停留,<2>删除2小时将使您恢复到以前的工作状态

答案 1 :(得分:1)

您可以使用相关子查询来匹配每个班次的开始和结束日期/时间。如果您的[HourRegistration]表包含

self.request

然后您可以使用代码...

创建名为[ShiftStartAndEnd]的已保存查询
EmployeeID  ClockDateTime        Type
----------  -------------------  ----
      1101  2016-09-04 09:00:00  IN  
      1101  2016-09-04 17:00:00  OUT 
      1102  2016-09-05 10:00:00  IN  
      1102  2016-09-05 15:00:00  OUT 
      1101  2016-09-05 17:00:00  IN  
      1101  2016-09-06 01:00:00  OUT 
      1101  2016-09-06 18:00:00  IN  
      1101  2016-09-07 01:00:00  OUT 

......返回......

SELECT 
    t1.EmployeeID, 
    t1.ClockDateTime AS StartDateTime, 
    (
        SELECT MIN(t2.ClockDateTime)
        FROM HourRegistration t2
        WHERE t2.EmployeeID = t1.EmployeeID
            AND t2.ClockDateTime > t1.ClockDateTime
            AND t2.Type='OUT'
    ) AS EndDateTime
FROM HourRegistration AS t1
WHERE t1.Type='IN';

然后你可以使用该保存的查询作为另一个使用DateDiff()计算正确移位长度的查询的基础,类似于你之前所做的...

EmployeeID  StartDateTime        EndDateTime        
----------  -------------------  -------------------
      1101  2016-09-04 09:00:00  2016-09-04 17:00:00
      1101  2016-09-05 17:00:00  2016-09-06 01:00:00
      1101  2016-09-06 18:00:00  2016-09-07 01:00:00
      1102  2016-09-05 10:00:00  2016-09-05 15:00:00

...返回

SELECT
    EmployeeId,
    StartDateTime AS ShiftStart,
    EndDateTime AS ShiftEnd,
    DateDiff("n", StartDateTime, EndDateTime) / 60 AS ShiftHours
FROM ShiftStartAndEnd