MYSQL&;PHP计算特定日期的总小时数,并排除重叠小时数
我有一个MYSQL任务表,其中每个任务都有一个日期、开始时间、结束时间和用户id。我想计算特定日期的总小时数 表格结构MYSQL&;PHP计算特定日期的总小时数,并排除重叠小时数,php,mysql,database,select-query,Php,Mysql,Database,Select Query,我有一个MYSQL任务表,其中每个任务都有一个日期、开始时间、结束时间和用户id。我想计算特定日期的总小时数 表格结构 CREATE TABLE tasks (`id` int,`user_id` int, `title` varchar(30), `task_date` datetime, `start` time, `end` time) ; INSERT INTO tasks (`id`,`user_id`, `title`,`task_date`, `start`, `
CREATE TABLE tasks
(`id` int,`user_id` int, `title` varchar(30), `task_date` datetime, `start` time, `end` time)
;
INSERT INTO tasks
(`id`,`user_id`, `title`,`task_date`, `start`, `end`)
VALUES
(1,10, 'Task one','2013-04-02', '02:00:00', '04:00:00'),
(2,10, 'Task two','2013-04-02', '03:00:00', '06:00:00'),
(3,10, 'Task three.','2013-04-02','06:00:00', '07:00:00');
MYSQL查询
select TIME_FORMAT(SEC_TO_TIME(sum(TIME_TO_SEC(TIMEDIFF( end, start)))), "%h:%i") AS diff
FROM tasks
where task_date="2013-04-02"
我得到的结果是“06:00”,这很好,但我想排除重叠时间。在我给出的示例中,当第二条记录中3-4之间的小时被排除时,结果应为“05:00”,因为该小时已存在于第1条记录中2-4之间
- 第一条记录2=>4=2小时
- 第二条记录3=>6=3小时3-1小时=2(1小时是第一条和第二条记录之间的重叠小时)
- 第三个6=>7=1
我希望我把问题说清楚示例这里有一个使用变量的想法(在其他数据库中,CTE和窗口函数会使这更容易)。我们的想法是首先列出所有的时间——开始和结束。然后,记录累计的启动和停止次数 当累积数大于0时,则包括与上一次的差异。如果等于0,则它是新时间段的开始,因此不添加任何内容 下面是一个查询示例,通过不跟踪
user\u id
中的更改,您的数据简化了一点:
select user_id, TIME_FORMAT(SEC_TO_TIME(sum(secs)), '%h:%i')
from (select t.*,
@time := if(@sum = 0, 0, TIME_TO_SEC(TIMEDIFF(start, @prevtime))) as secs,
@prevtime := start,
@sum := @sum + isstart
from ((select user_id, start, 1 as isstart
from tasks t
) union all
(select user_id, end, -1
from tasks t
)
) t cross join
(select @sum := 0, @time := 0, @prevtime := 0) vars
order by 1, 2
) t
group by user_id;
SQL FIDLE是否显示它正在工作。任务之间是否可能存在间隙?预期结果是什么样的?此外,通常最好将日期和时间存储为单个entity@PatrickQ是的,这是可能的(即TaskA 04:00-06:00,TaskB 07:00-08:00),在这种情况下,总时间将为3小时,因为从(04:00-06:00)开始是2小时,(07:00-08:00)开始是1小时。@草莓是的,您可以在单个实体中存储,但不会有任何区别。我给出的示例的预期结果是5小时。这可能是更好的代码。因此,编写一个查询,只返回每个任务的开始和结束时间。循环遍历结果数组,对于每一行,将
start
和end
之间的差异添加到$totalHours
变量中。然后,如果当前结束
和下一个开始
之间的差值为负值,则从$totalHours
中减去该值。如果任务可能并非总是在一小时内开始(例如,从5:25开始),那么在计算差异之前最好将其转换为秒。您是genius bro,感谢它按预期工作(:,但我的问题是,有没有其他方法可以不使用嵌套的选择查询来执行此操作?@Hadi.M有一种方法,但它速度较慢,而且同样复杂!