从datetime获取timepent从当前行到下一行mysql

时间:2017-05-01 16:43:20

标签: php mysql

您好我想计算并显示从当前行到下一行的datetime列之间所花费的时间。

当前表:

task_id | task    | date                | user_id
      1 | Task 1  | 2017-04-30 08:30:23 | 35
      2 | Task 2  | 2017-04-30 09:30:23 | 35
      3 | Task 3  | 2017-04-30 10:00:23 | 35

预期结果:

task_id | task    | date                | timespent
      1 | Task 1  | 2017-04-30 08:30:23 | 60
      2 | Task 2  | 2017-04-30 09:30:23 | 30
      3 | Task 3  | 2017-04-30 10:00:23 | (compute it by current time)

我有这样的查询,但似乎无法获得我的预期结果

SELECT A.task_id, A.date,A.task,A.user_id, 
TIMESTAMPDIFF(MINUTE,A.date,B.date) AS timespent
FROM tbl_task A CROSS JOIN tbl_task B
WHERE B.task_id IN (SELECT MIN(C.task_id) 
FROM tbl_task C 
WHERE C.task_id > A.task_id) 
AND A.user_id = 35
AND Month(A.date) = 5
ORDER BY A.task_id ASC

上述查询的问题是它无法获取最后一行,或者该行只是一条记录。我想计算当前时间的最后一条记录或单条记录时间(); 任何的想法?谢谢你的帮助。

3 个答案:

答案 0 :(得分:1)

要保留最后一行,您应该使用LEFT JOIN。 B.task_id的条件应该在ON子句中。您可以使用COALESCE(B.date, NOW())将NULL替换为当前时间戳。

SELECT A.task_id, A.date,A.task,A.user_id, 
TIMESTAMPDIFF(MINUTE,A.date, COALESCE(B.date, NOW())) AS timespent
FROM tbl_task A
LEFT JOIN tbl_task B ON B.task_id = (
    SELECT MIN(C.task_id) 
    FROM tbl_task C 
    WHERE C.user_id = A.user_id
      AND C.task_id > A.task_id) 
WHERE A.user_id = 35
  AND Month(A.date) = 5
ORDER BY A.task_id ASC

请注意,我还将C.user_id = A.user_id添加到子查询的WHERE子句中。否则,您可能会获得另一个用户task_id

由于您只需要下一行的date,因此您可以使用GROUP BY来避免使用子查询:

SELECT A.*, 
    TIMESTAMPDIFF(MINUTE,A.date, COALESCE(MIN(B.date), NOW())) AS timespent
FROM tbl_task A
LEFT JOIN tbl_task B
    ON  B.user_id = A.user_id
    AND B.task_id > A.task_id
WHERE A.user_id = 35
  AND Month(A.date) = 5
GROUP BY A.task_id
ORDER BY A.task_id ASC;

演示:http://rextester.com/SDWX89625

答案 1 :(得分:1)

使用外部联接。如果B.date为NULL,请改用NOW()

这样的事情:

 SELECT A.task_id
      , A.date
      , A.task
      , A.user_id
      , TIMESTAMPDIFF(MINUTE,A.date,IFNULL(B.date,NOW()) AS timespent
 --                                 ^^^^^^^      ^^^^^^^           
   FROM tbl_task A 
   LEFT
-- ^^^^
   JOIN tbl_task B
     ON B.task_id IN 
--   ^^   
                     ( SELECT MIN(C.task_id) 
                         FROM tbl_task C 
                        WHERE C.task_id > A.task_id
                     ) 
    AND A.user_id = 35
    AND MONTH(A.date) = 5
  ORDER BY A.task_id

答案 2 :(得分:1)

这应该有效:

SELECT 
    a.task_id, 
    a.date,
    a.task,
    a.user_id, 
    TIMESTAMPDIFF(MINUTE,a.date,IF(b.date IS NULL,CURRDATE(),b.date) AS timespent
FROM tbl_task a
LEFT JOIN tbl_task b
ON a.task_id > b.task_id
WHERE a.user_id = 35
AND month(a.date) = 5
GROUP BY a.task_id
ORDER BY a.task_id

基本上,通过使用左连接,没有匹配的记录将为其列提供空值。 timepent列测试null,并使用curr_date()代替。