我有两个具有以下结构的表。
我想获取start_date_time
和end_date_time
之间的时间(天,小时和分钟)。上午9点至下午5点之间的时间为工作时间,应仅考虑进行计算。例如,如果start_date_time
为2019-03-25 09:00:00
,而end_date_time
为2019-03-26 17:00:00
,则计算时间将为2天。如果end_date_time
是2019-03-26 12:00:00
,则计算的时间将是1天3小时。同一任务可以有多个时间条目,应该计算总时间。我已经尝试使用下面的查询来获取时间,但是它给出了总时间。我只想要9 AM到5 PM之间的时间。 DB Fiddle
SELECT t.task_name, sum(time_to_sec(timediff(end_date_time, start_date_time )) / 3600) FROM `task_time` tt left join task t on tt.task_id=t.task_id
group by tt.task_id
答案 0 :(得分:2)
最简单的处理方法是分别计算天数和小时数,然后将一天算为8小时。像这样:
SELECT t.task_name,
SUM(TIMESTAMPDIFF(DAY, DATE(start_date_time), DATE(end_date_time)) * 8 +
TIMESTAMPDIFF(MINUTE, TIME(start_date_time), TIME(end_date_time)) / 60) AS task_time
FROM task t
JOIN task_time tt ON tt.task_id = t.task_id
GROUP BY t.task_name
输出(用于我的演示数据)
task_name task_time
task1 16
task2 11
task3 4
更新
此查询将允许开始时间和结束时间在9 AM-5PM之外,而仅将9AM到5PM之间的小时数作为工作时间。通过使用GREATEST
和LEAST
将开始时间和结束时间强制设置为9 AM-5PM:
SELECT t.task_name,
SUM(TIMESTAMPDIFF(DAY, start_date, end_date) * 8 +
TIMESTAMPDIFF(MINUTE, TIME(start_time), TIME(end_time)) / 60) AS task_time
FROM task t
JOIN (SELECT task_id,
DATE(start_date_time) AS start_date,
DATE(end_date_time) AS end_date,
GREATEST('09:00', LEAST('17:00', TIME(start_date_time))) AS start_time,
GREATEST('09:00', LEAST('17:00', TIME(end_date_time))) AS end_time
FROM task_time) tt ON tt.task_id = t.task_id
GROUP BY t.task_name
更新2
此查询返回的时间为天,小时和分钟,而不仅仅是小时。
SELECT t.task_name,
days + FLOOR(minutes / 480) AS days,
CASE WHEN minutes < 0 THEN 8 + FLOOR(minutes % 480 / 60)
ELSE FLOOR(minutes % 480 / 60)
END AS hours,
CASE WHEN minutes < 0 THEN (60 + (minutes % 60)) % 60
ELSE minutes % 60
END AS minutes
FROM (SELECT t.task_name,
SUM(TIMESTAMPDIFF(DAY, start_date, end_date)) AS days,
SUM(TIMESTAMPDIFF(MINUTE, TIME(start_time), TIME(end_time))) AS minutes
FROM task t
JOIN (SELECT task_id,
DATE(start_date_time) AS start_date,
DATE(end_date_time) AS end_date,
GREATEST('09:00', LEAST('17:00', TIME(start_date_time))) AS start_time,
GREATEST('09:00', LEAST('17:00', TIME(end_date_time))) AS end_time
FROM task_time) tt ON tt.task_id = t.task_id
GROUP BY t.task_name) t