总结mysql中datetimes的多重DateDiff

总结mysql中datetimes的多重DateDiff,mysql,Mysql,我有一张桌子,有一个用户和一天的打卡次数(打卡、突破、突破、打卡)。现在假设用户休息2次或以上。我需要总结所有休息的总时间。我创建了一个sqlfiddle,以便更容易地显示我正在尝试做的事情。下面是我的例子:现在我需要取(12:30:21-12:04:44)+(12:36:00-12:34:00)来获得所有休息的总数。我该如何在我的查询中做到这一点。现在假设我的表中有10个用户和10天。我需要根据我知道的日期和用户进行分组。我首先要找到某种方法,将打卡记录与同一表中的打卡记录链接起来。然后,我们

我有一张桌子,有一个用户和一天的打卡次数(打卡、突破、突破、打卡)。现在假设用户休息2次或以上。我需要总结所有休息的总时间。我创建了一个sqlfiddle,以便更容易地显示我正在尝试做的事情。下面是我的例子:现在我需要取(12:30:21-12:04:44)+(12:36:00-12:34:00)来获得所有休息的总数。我该如何在我的查询中做到这一点。现在假设我的表中有10个用户和10天。我需要根据我知道的日期和用户进行分组。

我首先要找到某种方法,将打卡记录与同一表中的打卡记录链接起来。然后,我们可以将这些数据放入一个表中,并使用它来查询

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只计算两个日期之间的天数-它不用于时间。

这可能有效,我正在验证数据,如果它为我生成正确的结果,我将标记为答案。好的,如果您有任何问题,请告诉我-临时表在sqlfiddle上不起作用,只需删除该关键字并将其添加到架构部分。如果您想将其作为SQL的一部分,则只需将临时表的代码插入此fiddle中的select like-