Search code examples
c#sqlvisual-studiotimetime-and-attendance

Calculate absence time in day for employee


I have table to store attendance data of my employee as below:

EmployeeID|   Date   |EnterTime|ExitTime|
    1     |2017-01-01|07:11:00 |15:02:00|
    2     |2017-01-01|07:30:00 |12:00:00|
    2     |2017-01-02|07:00:00 |15:00:00|
    1     |2017-01-02|07:30:00 |10:00:00|
    1     |2017-01-02|11:20:00 |15:00:00|
    1     |2017-01-03|09:30:00 |10:00:00|
    1     |2017-01-03|11:20:00 |15:00:00|

Actually my working time is from 07:00:00 to 15:00:00 .

I want To sum up the absence time of each employee for example : in 2017-01-01 for employee ID 2 , is 03:00:00 hours as absence and in date 2017-01-02 for employee ID 1 is 01:00:00 hour. In Date 2017-01-03 , employee id 1 , is 02:30:00 and employee id 2 absence is 08:00:00 hour because there is no log in my table. Finally need following report:

EmployeeID|TotalWorkingHour       |TotalAbsenceHour|
    1     |sum(EnterTime-ExitTime)|05:09:00        |
    2     |sum(EnterTime-ExitTime)|11:30:00        |

I get total working seconds by following select,but don't know how to calculate absence seconds:

select EmployeeID,
sum(datediff(second,Convert(DATETIME, EnterTime, 114), Convert(DATETIME, ExitTime, 114)) ) as TotalWorkingSeconds 
from Attendance
where Attendance.Date between @FromDate and @ToDate 
and (EnterTime is not null) 
and (ExitTime is not null)
group by EmployeeID

Solution

  • It might be not the final and perfect solution, but it works out:

    DECLARE @StartDate DATE, @EndDate DATE
    SET @StartDate = '2016-12-31'
    SET @EndDate =  '2017-01-05' -- GETDATE()
    
    SELECT alldate_and_employee.EmployeeID
          ,alldate_and_employee.Date
          ,COALESCE(employee_workingdays.WorkingMinutes,0) as TimeWorked
          ,(alldate_and_employee.PlannedWorkingTime - COALESCE(employee_workingdays.WorkingMinutes,0)) as  WorkedTooLessMinutes
      FROM
      (
         -- returns a table with a combination of all Employees and all Dates
         SELECT DISTINCT EmployeeID, datelist.Date, 480 as PlannedWorkingTime
           FROM mytable
          CROSS JOIN
          (
            -- selects all dates between @StartDate and @Enddate
            SELECT DATEADD(DAY,number+1,@StartDate) [Date]
            FROM master..spt_values
            WHERE type = 'P'
            AND DATEADD(DAY,number+1,@StartDate) < @EndDate
          ) datelist
      ) alldate_and_employee
      LEFT OUTER JOIN
      (
          -- groups the working time of each employee for a working day
          SELECT EmployeeID
               ,Date 
               ,SUM(DATEDIFF(minute, EnterTime, ExitTime)) as WorkingMinutes
            FROM mytable
        GROUP BY EmployeeID
                ,Date 
      ) employee_workingdays
      ON employee_workingdays.Date       = alldate_and_employee.Date
     AND employee_workingdays.EmployeeID = alldate_and_employee.EmployeeID
    
    ORDER BY alldate_and_employee.Date, alldate_and_employee.EmployeeID