Mysql 获取两次约会之间上午9点到下午5点的时间

Mysql 获取两次约会之间上午9点到下午5点的时间,mysql,sql,Mysql,Sql,我有两张结构如下的桌子 任务表 任务时间表 我想得到开始日期时间和结束日期时间之间的时间,以天、小时和分钟为单位。上午9点至下午5点之间的时间为工作时间,应仅在计算时考虑。例如,如果开始日期时间为2019-03-25 09:00:00,结束日期时间为2019-03-26 17:00:00,则计算时间为2天。如果结束日期时间为2019-03-26 12:00:00,则计算时间为1天3小时。同一任务可以有多个时间条目,并且应计算总时间。我尝试使用下面的查询来获取时间,但它给出了总小时数。我只想要上午

我有两张结构如下的桌子

任务表 任务时间表 我想得到开始日期时间和结束日期时间之间的时间,以天、小时和分钟为单位。上午9点至下午5点之间的时间为工作时间,应仅在计算时考虑。例如,如果开始日期时间为2019-03-25 09:00:00,结束日期时间为2019-03-26 17:00:00,则计算时间为2天。如果结束日期时间为2019-03-26 12:00:00,则计算时间为1天3小时。同一任务可以有多个时间条目,并且应计算总时间。我尝试使用下面的查询来获取时间,但它给出了总小时数。我只想要上午9点到下午5点之间的几个小时


处理这个问题最简单的方法是分别计算天数和小时数,然后将一天计算为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点到下午5点之间,而仅将上午9点到下午5点之间的时间计算为工作时间。它的工作原理是使用最大值和最小值将开始和结束时间强制设置为上午9点到下午5点:

更新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

处理这个问题最简单的方法是分别计算天数和小时数,然后将一天计算为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点到下午5点之间,而仅将上午9点到下午5点之间的时间计算为工作时间。它的工作原理是使用最大值和最小值将开始和结束时间强制设置为上午9点到下午5点:

更新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

重要的是,我们只考虑9AM-5PM之间的时间。@ USE1690835,只要开始和结束时间在上午9点到下午5点之间,这将是这样。他们可能不会吗?可能不会。我在问题中添加了DB提琴。如果用户加班,则不会考虑。如果他需要上午9点到晚上8点完成一项任务,则只考虑上午9点到下午5点。我知道这是一个复杂的查询,这就是我寻求帮助的原因。@user1690835不用担心,只是想确定一下。看看我的编辑。重要的是我们应该只考虑9AM-5PM之间的时间。@ USE1690835,只要开始和结束时间在上午9点到下午5点之间,就可以做到。他们可能不会吗?可能不会。我在问题中添加了DB提琴。如果用户加班,则不会考虑。如果他需要上午9点到晚上8点完成一项任务,则只考虑上午9点到下午5点。我知道这是一个复杂的查询,这就是我寻求帮助的原因。@user1690835不用担心,只是想确定一下。请参阅我的编辑。