计算同一表上各行之间的日期时间行之间的差异 [英] Calculating difference on datetime row betwen rows on the same table

查看:88
本文介绍了计算同一表上各行之间的日期时间行之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表,其中包含触发时任务,状态和时间的记录:

I have table that holds records with tasks, status and time when triggered:

表格表:

+-------------+------------+---------------------+-----+
| task        | status     | stime               | id  |
+-------------+------------+---------------------+-----+
| A           | 1          | 2018-03-07 20:00:00 | 1   |
| A           | 2          | 2018-03-07 20:30:00 | 2   |
| A           | 1          | 2018-03-07 21:00:00 | 3   |
| A           | 3          | 2018-03-07 21:30:00 | 4   |
| B           | 1          | 2018-03-07 22:30:00 | 5   |
| B           | 3          | 2018-03-07 23:30:00 | 6   |
+-------------+------------+---------------------+-----+

状态1表示开始,2-暂停,3-结束

Status 1 means start, 2 - pause, 3 - end

然后,我需要计算除暂停(状态= 2)外,每个任务花费了多少时间.这是我的方法:

Then I need to calculate how much time is spent for each task excluding pause (status = 2). This is how I do it:

SELECT t1.id, t1.task,
SUM(timestampdiff(second,IFNULL( 
(SELECT MAX(t2.stime) FROM tblwork t2  WHERE t2.task='B' AND t2.stime< t1.stime) ,t1.stime),t1.stime)) myTimeDiffSeconds
FROM tblwork t1 
WHERE t1.task='B' and (t1.status = 1 or t1.status = 3);

现在我要获取所有任务的表

Now I want to get table for all tasks

SELECT t1.id, t1.task,
SUM(timestampdiff(second,IFNULL( 
(SELECT MAX(t2.stime) FROM tblwork t2  WHERE t2.stime< t1.stime) ,t1.stime),t1.stime)) myTimeDiffSeconds
FROM tblwork t1 
WHERE (t1.status = 1 or t1.status = 3) GROUP BY t1.taks

我得到这个结果:

+-------------+------------+---------------------+
| task        | id         | mytimedifference    |
+-------------+------------+---------------------+
| A           | 1          | 3600                |   
| B           | 3          | 2421217             |
+-------------+------------+---------------------+

计算A是正确的B是错误的,应该是3600秒,但我不明白为什么.

Calculation for A is correct B is wrong, it should be 3600 second but i don't understand why.

推荐答案

假设每次暂停和结束总是有一个起点,那么这样会更直接吗?

Assuming there is always a start for each pause and end, wouldn't something like this be more direct?

SELECT t.task
   , SUM(TO_SECONDS(t.stime) 
         * CASE WHEN t.status IN (1) THEN -1
                WHEN t.status IN (2, 3) THEN 1
                ELSE 0
           END
     ) AS totalTimeSecs
FROM tblwork AS task
GROUP BY t.task

我不太确定TO_SECONDS()产生的值对于当前时间戳有多大;但是如果将它们加在一起是一个问题,可以将其更改为

I'm not quite sure offhand how big the values that come out of TO_SECONDS() are for current timestamps; but if they are an issue when being summed, if could be changed to

   , SUM((TO_SECONDS(t.stime) - some_constant_just_before_or_at_your_earliest_seconds)
         * CASE WHEN t.status IN (1) THEN -1
                WHEN t.status IN (2, 3) THEN 1
                ELSE 0
           END
     ) AS totalTimeSecs


您可以通过将以下内容添加到选择表达式列表中来检测异常"数据


You can detect "abnormal" data by adding the following to the select expression list

, CASE WHEN SUM(CASE 
                WHEN t.status IN (1) THEN -1 
                WHEN t.status IN (2, 3) THEN 1 
                ELSE 0 END
              ) = 0 
       THEN 'OK' 
       ELSE 'ABNORMAL' 
   END AS integrityCheck

注意:任何未封闭"的间隔都将被标记为异常;如果没有更复杂,更昂贵的开始和结束检查间隔来区分打开"和无效",那么可能是最好的选择. 用于附加"integrityCheck"的总和等于-1可能暗示一个开放的时间间隔,但也可能指示错误的双开始.

Note: any "unclosed" intervals will be marked as abnormal; without much more complicated and expensive start and end checking for intervals to differentiate "open" from "invalid", it's probably the best that can be done. The sum used for additonal "integrityCheck" equaling -1 might hint at an open ended interval, but could also indicate an erroneous double-start.

这篇关于计算同一表上各行之间的日期时间行之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆