I’m trying to calculate regular an overtime hours for an employee that works 2 jobs at the same company. The reason it needs to be done this way, is the hours get billed to separate departments. Overtime begins after the employee works 40 total hours, and anything beyond is considered Overtime for the respective job. I basically need (4) different numbers out of the sql statement. I need:
Job 1 Regular hours
Job 1 Overtime hours
Job 2 Regular hours
Job 2 Overtime hours
My current sql query to achieve the table below is:
SELECT clockPunch.punchinTime, clockPunch.punchoutTime, clockPunch.job, ROUND(CEIL((TIME_TO_SEC(TIMEDIFF(clockPunch.punchoutTime, clockPunch.punchinTime))/3600.0)*10)/10, 2) AS timedifference FROM clockPunch WHERE clockPunch.employee_id=1 order by punchinTime DESC
My current table looks like below:
employee punchinTime punchoutTime job timedifference
1 2023-06-22 08:00:00 2023-06-22 17:00:00 1 9.00
1 2023-06-23 09:00:00 2023-06-23 17:30:00 1 8.50
1 2023-06-24 11:00:00 2023-06-24 20:00:00 2 9.00
1 2023-06-25 09:00:00 2023-06-25 17:00:00 1 8.00
1 2023-06-26 13:00:00 2023-06-26 23:00:00 2 10.00
1 2023-06-27 14:30:00 2023-06-28 01:00:00 2 10.50
1 2023-06-28 14:00:00 2023-06-28 19:00:00 2 5.00
1 2023-06-29 09:00:00 2023-06-29 17:00:00 1 8.00
For the above data, I am trying to write a new query, but am unsure how to. I want the new query to show the following result:
Job 1 Regular hours: 25.50
Job 1 Overtime hours: 8.00
Job 2 Regular hours: 14.50
Job 2 Overtime hours: 20.00
Does anyone have any advice on how to achieve this through an sql query?
2
Answers
I don’t have time to write out a complete query to do everything you need, but this will calculate how many total hours the employee has worked after the current punch out:
After this, you can calculate how much time from the current punch is overtime by subtracting 40 from the total. Whichever value is smaller, the remainder of the total or the value in timedifference, is the overtime from that punchin.
Then it is a matter of using some aggregate functions to sum up your overtime and regular hours by job.
NOTE: This does not take into consideration the fact that there are times from multiple weeks in the provided data. The
WEEKOFYEAR()
function will help in grouping each weeks worth of data together.We can use
SUM()
as a window function to get the cumulative total hours:Which will output:
Now we can use the above query as a derived table and figure out which hours are regular and which are overtime:
Which give us:
And then to pull it all together we can group by
job
:Et voilà:
Your demo data is Thursday to Thursday inclusive so I have not added the partitioning or grouping by week, but hopefully this enough to get you going.