我有一张桌子,有一个用户和一天的拳击(clockin,breakout,breakin,clockout)。现在说用户需要休息两次或更多次。我需要总结所有休息时间的总时间。我创建了一个sqlfiddle,以便更容易地显示我想要做的事情。这是我的例子:http://sqlfiddle.com/#!2/21542/6现在我需要(12:30:21 - 12:04:44)+(12:36:00 - 12:34:00)来获取所有休息的总数。我怎么能在我的查询中这样做。现在假装我的桌子上有10个用户和10天。我需要按天分组和我认识的用户。
答案 0 :(得分:0)
我首先会找到一些方法将打孔记录与来自同一张表的打卡记录联系起来。然后我们可以将这些数据放入表中并用它来查询。
CREATE TEMPOARY TABLE breakPunchInOut (
SELECT
DATE(punchout.PunchDateTime) AS ShiftDate,
punchout.EmpId,
punchout.PunchId AS PunchOutID,
(SELECT
PunchId
FROM
timeclock
WHERE
timeclock.EmpId = punchout.EmpId
AND
timeclock.`In-Out` = 1
AND
timeclock.PunchDateTime > punchout.PunchDateTime
AND
DATE(timeclock.PunchDateTime) = DATE(punchout.PunchDateTime)
ORDER BY
timeclock.PunchDateTime ASC
LIMIT 1
) AS PunchInID
FROM
timeclock AS punchout
WHERE
punchout.`In-Out` = 0
HAVING
PunchInID IS NOT NULL
);
此查询的工作方式是查找特定日期内的所有“打卡”,然后针对每一个,它会查找由同一个人在同一天发生的下一次“打卡”。 HAVING子句过滤掉打出后没有打卡的记录 - 所以也许员工回家当天。这是值得记住的事情,因为如果有人在轮班中途回家,那么他们的休息时间将不会被添加到总数中。
重要的是要指出这种方法只适用于同一天开始和结束的班次。如果你的夜班从晚上开始,到第二天早上结束,那么你将不得不改变你加入拳击的方式并一起打卡。
现在我们有了这个链接表,使用它来创建每个员工和每个班次的摘要报告相对简单:
SELECT
breakPunchInOut.ShiftDate,
breakPunchInOut.EmpId,
SUM(
TIMESTAMPDIFF(MINUTE, punchOut.PunchDateTime, punchIn.PunchDateTime)
) AS TotalBreakLengthMins
FROM
breakPunchInOut
INNER JOIN
timeclock AS punchOut
ON
punchOut.PunchId = breakPunchInOut.PunchOutId
INNER JOIN
timeclock AS punchIn
ON
punchIn.PunchId = breakPunchInOut.PunchInId
GROUP BY
breakPunchInOut.ShiftDate,
breakPunchInOut.EmpId
;
注意我们使用TIMESTAMPDIFF函数,而不是DATEDIFF。 DATEDIFF仅计算两个日期之间的天数 - 它不用于时间。