标题可能有点令人困惑,所以请允许我解释一下.我正在使用表来记录我的工作日志.每天我都会创建一个条目,说明我工作的时间和时间,我会添加评论来描述我的所作所为.
然后,我使用查询来比较时间戳,以确定我当天工作了多少小时和分钟.另外,我使用查询来计算我整年工作的小时和分钟的总和.这就是我遇到问题的地方.我的查询如下.
SELECT TIME_FORMAT(SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(entry_end_time, entry_start_time)))), '%H:%i')
AS total FROM entry
WHERE entry_date BETWEEN '2012-01-01' AND '2012-12-31' AND user_id = 3
Run Code Online (Sandbox Code Playgroud)
默认情况下,MySQL TIME字段允许的时间范围为"-838:59:59"到"838:59:59".我今年已经记录了超过900小时的工作,我希望我的查询结果能够反映出这一点.相反,结果是838:59:59,这是有道理的,因为这是限制.
有没有办法绕过这个,所以查询的结果可以超过839小时,或者我是否必须使用像PHP这样的东西来遍历整个表并将其全部添加?如果可能的话,我有点想避免这种情况.
看一下timestampdiff,它没有时间限制。即类似(未经测试):
SELECT CONCAT(
TIMESTAMPDIFF(HOURS, entry_end_time, entry_start_time),
":",
MOD(TIMESTAMPDIFF(MINUTES, entry_end_time, entry_start_time),60)
)
AS total FROM entry
WHERE entry_date BETWEEN '2012-01-01' AND '2012-12-31' AND user_id = 3
Run Code Online (Sandbox Code Playgroud)
连接并不理想,我相信会有一个更优雅的解决方案。
我只是检索工作的总秒数,并在我的应用程序的表示层中根据需要转换为小时/分钟(毕竟,这是一个简单的除以60的情况):
<?
$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$qry = $dbh->prepare('
SELECT SUM(TIME_TO_SEC(entry_end_time)-TIME_TO_SEC(entry_start_time))
FROM entry
WHERE entry_date BETWEEN :start_date AND :end_date
AND user_id = :user_id
');
$qry->execute([
':start_date' => '2012-01-01',
':end_date' => '2012-12-31',
':user_id' => 3
]);
list ($totalMins, $remngSecs) = gmp_div_qr($qry->fetchColumn(), 60);
list ($totalHour, $remngMins) = gmp_div_qr($totalMins, 60);
echo "Worked a total of $totalHour:$remngMins:$remngSecs.";
?>
Run Code Online (Sandbox Code Playgroud)