Ryan McDevitt
Ryan McDevitt

Reputation: 73

Calculating Total Overtime MySQL

I am creating a timeclock system and management website. I am trying to pull the amount of overtime for a particular department with a MySQL query.

The timeclocks update a MySQL table called events, which stores the employee_id, the job they are working on, the time_in and the time_out. I can produce a table of the total hours worked from each employee_id with:

SELECT employee_id, 
       SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))) AS hours 
  FROM events 
 GROUP BY employee_id;

This will return a table of employee_ids and the total hours they worked. To create a table of employee_ids overtime I use:

SELECT employee_id,
       IF(HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))>40,
          HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))-40,
          0) AS overtime 
  FROM events 
  GROUP BY employee_id;

This returns a table of employee_ids and the amount of overtime they have worked.

The trouble I am having starts when I want to find a total of the overtime worked for all employees. I assumed I would be able to just put the IF function to find overtime inside of SUM() however when i run the following statement:

SELECT SUM(IF(HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))>40,
              HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))-40,
              0)) AS overtime 
 FROM events;

I get this error back:

ERROR 1111 (HY000): Invalid use of group function

I have looked all over for this but have found little in way of SUM(IF(SUM())) functions.

Note: The overtime has to be calculated individually, I cant just take total hours worked / number of employees - 40. If one worker works 30 hours in a week, and another works 50, there are 10 hours of overtime, but the average says there isn't any.

Upvotes: 0

Views: 2830

Answers (2)

O. Jones
O. Jones

Reputation: 108796

How about this?

SELECT SUM(overtime)
  FROM
  (
    SELECT employee_id,
           IF(HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))>40,
              HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))-40,
              0) AS overtime 
      FROM events 
     GROUP BY employee_id
  )TOTAL

When you're using SQL to implement complex business logic, nested queries have a key advantage: they let you test each level of the logic and build it up in a reliable way.

Upvotes: 2

user496607
user496607

Reputation: 442

Just add this to the above answer by Ollie:

SELECT SUM(overtime)
  FROM
  (
    SELECT employee_id,
           IF(HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))>40,
              HOUR(SEC_TO_TIME(SUM(TIMEDIFF(time_out,time_in))))-40,
              0) AS overtime 
      FROM events
     GROUP BY employee_id
  ) TOTAL_OVERTIME

You need to name your derived table for the code to work.

Upvotes: 1

Related Questions