我正在评估与SO相关的提议解决方案与MySQL中重叠日期时间的总和。我无法找到一个银弹解决方案,所以想知道是否有任何经典/工业级算法程序,或者是否需要开发定制的。
总计应为8小时(4 + 4)。
通过MySQL提出的解决方案
function final_balance($teacher_id, $aa, $teaching_id=0) {
$dbo = $this->Attendance->getDataSource();
$years=$this->Attendance->Student->Year->find('list', array('fields' => array('anno', 'data_from')));
$filteraa='attendances.start>="'.$years[$aa].'"';
$this->query('SET @interval_id = 0');
$this->query('SET @interval_end = \'1970-01-01 00:00:00\'');
$sql='SELECT
MIN(start) as start,
MAX(end) as end
FROM (
SELECT
@interval_id := IF(attendances.start > @interval_end, @interval_id + 1, @interval_id) AS interval_id,
@interval_end := IF(attendances.start < @interval_end, GREATEST(@interval_end, attendances.end), attendances.end) AS interval_end,
attendances.start,
attendances.end
FROM attendances
INNER JOIN attendance_sheets ON (
attendance_sheet_id = attendance_sheets.id AND
attendance_sheets.teacher_id='.$teacher_id.' AND '.$filteraa.' AND
attendance_sheet_status_id = 2 AND
attendance_status_id!=3'.
($teaching_id?' AND attendances.teaching_id IN ('.$teaching_id.')':'').'
)
ORDER BY attendances.start,attendances.end
) intervals GROUP BY interval_id';
// final query to sum in the temp table
$finalStatement =array(
'table' => $dbo->expression('('.$sql.')')->value,
'alias' => 'Attendance',
'fields' => array(
'DATE_FORMAT(start, \'%d/%m/%Y\') as data',
'DATE_FORMAT(start, \'%m-%Y\') as datamese',
'DATE(start) as datasql',
$teacher_id.' AS teacher_id',
'DAY(start) as giorno',
'MONTH(start) as mese',
'YEAR(start) as anno',
'SEC_TO_TIME(SUM((TIME_TO_SEC(end) - TIME_TO_SEC(start)))) as ore',
),
'conditions' => array(),
'limit' => null,
'group' => array('CONCAT(YEAR(start),MONTH(start))', 'DATE(start) WITH ROLLUP'),
'order' => null
);
$finalQuery= $dbo->buildStatement($finalStatement, $this->Attendance);
return $this->Attendance->query($dbo->expression($finalQuery)->value);
}
参考
Sum amount of overlapping datetime ranges in MySQL 执行不同的任务
MySQL: sum time ranges exluding overlapping ones 和 MySQL: sum datetimes without counting overlapping periods twice 在我看来,似乎没有考虑所有案例
答案 0 :(得分:0)
根据具体情况,以下内容可能有用且有效。
创建另一个每小时有一行的表。将表与表一起内连接,同时仅选择新列并重复行。
您可以不断提高分辨率(例如分钟或秒),但这可能会导致代码运行缓慢。