Reputation: 73
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_id
s and the total hours they worked. To create a table of employee_id
s 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_id
s 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
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
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