patternsqlMinor
Total hours worked per employee per day including overnight sessions
Viewed 0 times
totalemployeeperhoursworkedovernightincludingdaysessions
Problem
I have a table like this:
primary key omitted for brevity - please see http://www.sqlfiddle.com/#!9/30503/1
0 means login - 1 means logout. There can be several logins/logouts per user per day or period of days if for example an employee works overnight (as employee 5 does between 2014-03-02 and 2014-03-03 )
I am trying to get the total sum of hours worked per employee per day/shift (e.g. some shifts will span over two days):
I came up with this query:
Which only gave me the time e
CREATE TABLE Table1
(ID int, empid int, time datetime, state int);
+--------------+---------------------+-----------------+
| empid | time | state |
+--------------+---------------------+-----------------+
( 4 | 2014-03-01 11:12:00 | 0 )
( 5 | 2014-03-01 12:28:06 | 0 )
( 4 | 2014-03-01 12:50:07 | 1 )
( 4 | 2014-03-01 13:38:00 | 0 )
( 5 | 2014-03-01 13:28:06 | 1 )
( 4 | 2014-03-01 18:42:15 | 1 )
( 4 | 2014-03-02 08:11:08 | 0 )
( 4 | 2014-03-02 13:26:11 | 1 )
( 5 | 2014-03-02 14:16:15 | 0 )
( 4 | 2014-03-02 16:16:15 | 0 )
( 5 | 2014-03-02 17:48:21 | 1 )
( 4 | 2014-03-02 19:39:03 | 1 )
( 5 | 2014-03-02 20:16:15 | 0 )
( 5 | 2014-03-03 04:16:15 | 1 )
+--------------+---------------------+-----------------+primary key omitted for brevity - please see http://www.sqlfiddle.com/#!9/30503/1
0 means login - 1 means logout. There can be several logins/logouts per user per day or period of days if for example an employee works overnight (as employee 5 does between 2014-03-02 and 2014-03-03 )
I am trying to get the total sum of hours worked per employee per day/shift (e.g. some shifts will span over two days):
1 2014-03-02 total hours worked 08:32:00I came up with this query:
SELECT CONCAT(
MOD(TIMEDIFF(MAX(CASE WHEN state = '1' THEN time END),
MIN(CASE WHEN state = '0' THEN time END)), 24 ), ' hours ',
MINUTE(TIMEDIFF(MAX(CASE WHEN state = '1' THEN time END),
MIN(CASE WHEN state = '0' THEN time END))), ' minutes') as HoursWorked,
empid,
Date(time)
FROM emplog T
GROUP BY empid, Date(time)Which only gave me the time e
Solution
Please check if the performance is sufficient:
Edit
To aggregate per day:
SELECT empid
,SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND, time, (SELECT IFNULL(MIN(time),NOW())
FROM emplog b
WHERE b.empid = a.empid
AND b.time > a.time
AND b.state = 1
)))) date_worked
FROM emplog a
WHERE state=0
GROUP BY empid;Edit
To aggregate per day:
SELECT empid
,DATE(time) day
,SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND, time, (SELECT IFNULL(MIN(time),NOW())
FROM emplog b
WHERE b.empid = a.empid
AND b.time > a.time
AND b.state = 1
)))) date_worked
FROM emplog a
WHERE state=0
GROUP BY empid, DATE(time);Code Snippets
SELECT empid
,SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND, time, (SELECT IFNULL(MIN(time),NOW())
FROM emplog b
WHERE b.empid = a.empid
AND b.time > a.time
AND b.state = 1
)))) date_worked
FROM emplog a
WHERE state=0
GROUP BY empid;SELECT empid
,DATE(time) day
,SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND, time, (SELECT IFNULL(MIN(time),NOW())
FROM emplog b
WHERE b.empid = a.empid
AND b.time > a.time
AND b.state = 1
)))) date_worked
FROM emplog a
WHERE state=0
GROUP BY empid, DATE(time);Context
StackExchange Database Administrators Q#130676, answer score: 5
Revisions (0)
No revisions yet.