我正在开发一个员工登录系统,其中用户登记和结账时间是记录器。我有以下mySql表模式,我想从中查询特定月份员工的总工作时间。
AttendanceId UserId Operation CreatedDate
24 4 1 2016-03-20 23:18:59
25 4 2 2016-03-20 23:19:50
26 4 1 2016-03-20 23:20:28
27 4 2 2016-03-20 23:20:31
操作1用于登记,操作2用于结账。任何人都可以帮我构建这个查询吗?
答案 0 :(得分:0)
一个令人愉快的问题,谢谢。我的查询涉及:
我使用以下数据进行测试:
INSERT INTO Attendance(UserId, Operation, CreatedDate) VALUES
(4, 1, '2016-01-01 15:00:00'),
(4, 2, '2016-01-01 19:00:00'),
(4, 1, '2016-01-31 23:00:00'),
(4, 2, '2016-02-01 01:00:00'),
(4, 1, '2016-02-20 23:18:59'),
(4, 2, '2016-02-20 23:19:50'),
(4, 1, '2016-02-20 23:20:28'),
(4, 2, '2016-02-20 23:20:31'),
(4, 1, '2016-02-29 23:00:00'),
(4, 2, '2016-03-01 01:00:00'),
(4, 1, '2016-03-02 15:00:00'),
(4, 2, '2016-03-02 18:00:00'),
(4, 1, '2016-03-22 10:00:00');
查询选择所有用户'特定月份的小时数。在一个查询中选择结果超过一个月会更复杂,因为考勤可能跨越月边界,如果需要,可能最简单的迭代几个月并重复运行查询,适当调整SQL中的四个日期。 / p>
最里面的查询为所有用户选择所有到达时间和相应的出发时间。外部查询然后将它们限制为当前月份,计算两次之间的差异,并按用户对它们求和。
SELECT UserId, SUM(TIMESTAMPDIFF(
SECOND,
GREATEST(TimeIn, '2016-02-01'),
LEAST(COALESCE(TimeOut, NOW()), '2016-03-01'))) / 3600 HoursInMonth
FROM (SELECT TimeIn.UserId, TimeIn.CreatedDate TimeIn, MIN(TimeOut.CreatedDate) TimeOut
FROM Attendance TimeIn
LEFT JOIN Attendance TimeOut ON TimeOut.UserId = TimeIn.UserId
AND TimeOut.Operation = 2
AND TimeOut.CreatedDate > TimeIn.CreatedDate
WHERE TimeIn.operation = 1
GROUP BY TimeIn.AttendanceId
ORDER BY TimeIn.CreatedDate) TimeInOut
WHERE DATE_FORMAT(TimeIn, '%Y-%m') = '2016-02'
OR DATE_FORMAT(TimeOut, '%Y-%m') = '2016-02'
OR (DATE_FORMAT(TimeIn, '%Y-%m') < '2016-02' AND TimeOut IS NULL)
GROUP BY UserId;