MySQL - 每天汇总时段/班次

时间:2015-08-27 20:27:32

标签: mysql sql sum

让我们假设我们有一种shift-scheduler应用程序。您可以将用户置于轮班/时隙中。有一个摘要视图,显示一个人每天需要多少小时才能正确填充计划的班次(时间差在min(shift.start)和max(shift.end)之间)。另一个值是与人/天相关的班次/时隙的总和。

示例:

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

现在,如果一个人只在Shift 1和Shift 4中,那么很容易对变化进行补偿。这将使upp达到3小时。但是,如果这个人在所有班次(1-5)中被推荐,那么这不再是微不足道的(因为时间平行或重叠)。现在你需要忽略具有相同时隙的移位(移位1和2相等,因此只有一个应该计数)并且还移位位于其他移位的时间(如移位3,在移位1和2的插槽中) 。 Shift 5在班次4的时间段中间开始,但持续时间更长,因此只有delta才能计算。

我的问题是:是否可以直接在sql语句(mysql)中计算一个人/天的班次总和?上述示例的简单SUM为7小时。但正确的SUM(考虑平行或重叠的移位等)将使3小时和30分钟。我从来没有找到这个问题的答案,只是通过shift.start,shift.end或DISTINCT shift.start,shift.end分组来消除相同的班次。

这是可以求和并忽略并行移位(相同时隙)的查询示例。

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

有一个表格移位可以保存所有班次信息(开始,结束等)。另一个表是user_shift,它包含idShift和idUser(其中shift是用户调度的)。查询获取shift.id(12126),获取该班次的日期以获得同一天的其他班次。稍后,加入会将当天的所有班次与用户ID进行匹配。示例结果是(idUser:123 | sumD:5h 30m)。

1 个答案:

答案 0 :(得分:0)

逻辑是:

  1. 请注意表格中第一个班次的开始,定义您的总和。
  2. 获得下一个开始/结束。
  3. 如果表为空,请添加starttime
  4. 如果它是表格中第一个条目的结尾,请总结。
  5. 如果是结束,请从表中删除相应的开头。
  6. 如果是开头,请将其添加到您的表格中。
  7. 如果您的列表不为空,请转到2.
  8. 我认为不可能将其作为一个查询,即使可能,构建该逻辑也不是一个简单的查询,也许可以考虑不在sql服务器上进行。