MySQL-总结每天的轮班时间

MySQL-总结每天的轮班时间,mysql,sql,sum,Mysql,Sql,Sum,让我们假设我们有一种移位调度器应用程序。您可以将用户设置为轮班/时隙。有一个摘要视图,显示一个人每天需要多少小时才能正确完成计划的轮班(最小值(班次.开始)和最大值(班次.结束)之间的时间差)。另一个值是与一个人/天相关的班次/时间段的总和 例如: Shift 1 | Start: 27.08.2015 08:00 | End: 27.08.2015 10:00 Shift 2 | Start: 27.08.2015 08:00 | End: 27.08.2015 10:00 Shift 3 |

让我们假设我们有一种移位调度器应用程序。您可以将用户设置为轮班/时隙。有一个摘要视图,显示一个人每天需要多少小时才能正确完成计划的轮班(最小值(班次.开始)和最大值(班次.结束)之间的时间差)。另一个值是与一个人/天相关的班次/时间段的总和

例如:

Shift 1 | Start: 27.08.2015 08:00 | End: 27.08.2015 10:00
Shift 2 | Start: 27.08.2015 08:00 | End: 27.08.2015 10:00
Shift 3 | Start: 27.08.2015 08:30 | End: 27.08.2015 09:30
Shift 4 | Start: 27.08.2015 10:00 | End: 27.08.2015 11:00
Shift 5 | Start: 27.08.2015 10:30 | End: 27.08.2015 11:30
现在,如果一个人只在第1班和第4班,就很容易总结出班次。那总共是3个小时。但如果该人员被安排在所有班次(1-5)中,这不再是微不足道的(因为平行或重叠的时间段)。现在,您需要忽略具有相同时隙的班次(班次1和2相等,因此只有一个班次应该计算),以及位于其他班次时间的班次(如班次3,位于班次1和2的插槽中)。换档5在换档4的时隙中间开始,但持续时间较长,所以只有三角洲应该计数。 我的问题是:是否可以直接在sql语句(mysql)中计算一个人/天的班次总和?上述示例的简单总和为7小时。但正确的总和(考虑平行或重叠轮班等)将为3小时30分钟。我从未找到该问题的答案,只是通过按班次、开始、结束或不同的班次、开始、结束分组来消除相等的班次

这是一个可以汇总并忽略并行移位(相同时隙)的查询示例

有一个包含所有班次信息(开始、结束等)的表班次。另一个表是user_shift,其中包含idShift和idUser(其中shift是用户计划的)。查询获取一个shift.id(12126),获取该班次的日期以获取当天的其他班次。稍后,Join会将当天的所有班次与用户id相匹配。示例结果是(idUser:123 | sumD:5h 30m)。

逻辑是:

  • 注意表中第一个班次的开始,定义您的总和
  • 获得下一个起点/终点
  • 如果表为空,请添加starttime
  • 如果它是表中第一个条目的末尾,则求和
  • 如果是结束,请从表中删除相应的开始
  • 如果这是一个开始,请将其添加到表中
  • 如果您的列表不是空的,请转到2

  • 我不认为有可能作为一个查询,即使可能的话,为这个逻辑构建也不是一个容易的查询,也许考虑不在SQL Server上实现。

    你有一个同时处于两个班的人吗?是的,可能是。它更像是一个逻辑移位结构,而不是物理移位结构:)。平行移动是可能的。我们不要假设任何事情。相反,如果你喜欢,考虑以下简单的两步行动:1。如果您还没有这样做,请提供适当的DDL(和/或SQLFIDLE),以便我们可以更轻松地复制问题。2.如果您尚未这样做,请提供与步骤1中提供的信息相对应的所需结果集。谢谢!听起来像图灵机器:-)。但问题是,是否有可能通过SQL查询获得总和。现在这是一个理论问题。我会尽量为这个问题提供sqlfiddle,就像草莓在他/她的评论中建议的那样。
    SELECT
    
    us.idUser, 
    
    CONCAT(SUBSTR(SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(sh.end, sh.start)))),1,2),"h ",
    SUBSTR(SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(sh.end, sh.start)))),4,2),"m") AS sumD
    
    FROM
    (
    
    SELECT start, end, id
    FROM shift
    WHERE (DATE(shift.start) = (SELECT DATE(shift.start) FROM shift WHERE shift.id = 12126))
    GROUP BY start, end
    
    ) sh
    
    LEFT JOIN user_shift us
    ON sh.id = us.idShift
    
    GROUP BY us.idUser