当主键不连续时,计算两行之间的时间差。怎么样?

时间:2019-03-05 00:15:35

标签: mysql

经过大量审查,我确定了我认为有效的查询存在的问题。

下面的MySQL查询用于获取表中2条记录之间的时间差。如果表中只有一个用户ID并且主键是连续的,那么一切都会正常进行。

SELECT USER_ID,
       UTL_TASK,
       SUM(UTL_DURATION) AS UTL_DURATION_TOTAL       
  FROM (

SELECT A.PK_USER_TIME_LOG_ID,
       A.CLIENT_ID,
       A.PROJECT_ID,
       A.USER_ID,
       A.UTL_DTSTAMP,
       /* DATE_FORMAT(A.UTL_DTSTAMP,'%H:%i:%s') AS UTL_DTSTAMP, */
       A.UTL_LATITUDE,
       A.UTL_LONGITUDE,
       A.UTL_EVENT,
       A.UTL_TASK,
       /* DURATION in seconds  */
       TIMESTAMPDIFF(SECOND, A.UTL_DTSTAMP, B.UTL_DTSTAMP) AS UTL_DURATION
FROM   tbl_user_time_log A
       INNER JOIN tbl_user_time_log B
               ON B.PK_USER_TIME_LOG_ID = ( A.PK_USER_TIME_LOG_ID + 1 )
WHERE  A.USER_ID = '465615'
       /* Between current pay period Start date and Current pay period end date */
       /* First day of the week is Monday.*/
       AND ( A.UTL_DTSTAMP BETWEEN '2019-03-04' AND '2019-03-12' )
       /* Filter out Clock Out. */
       AND A.UTL_EVENT <> 'CLOCK OUT'

  /* Our derived table... */
) AS tbl_derived_1

GROUP BY USER_ID, UTL_TASK;

工作场景示例:

working

非工作场景示例:

如您所见,此示例中的第一个橙色条目需要从时钟退出条目标记中减去,因为它是时钟退出之前的最后一个标记。相反,查询实际上是从下一行减去中?????

nonworking

如何修改此查询以考虑以下条件:

A。下一个连续记录和插入的各个时间戳记可以或可以不由同一用户标识添加。如果不是同一用户ID,则查询将继续在行中添加下一条记录。

基本上,即使我尝试按USER_ID 465615进行过滤,查询也只会继续添加行中的下一条记录,无论该记录是否属于此用户ID。

为什么?

以下是我在此网站上找到的最接近的,以可能解决此差异。

https://stackoverflow.com/a/7937333/687137

免责声明:此链接不构成重复。如果您只是在读类似的英语单词,并且想像是投下反对票而又不真正了解网站内容和此特定问题之间的区别,请继续前进

1 个答案:

答案 0 :(得分:2)

您应该可以将JOIN的条件更改为:

INNER JOIN tbl_user_time_log B
    ON B.UTL_DTSTAMP = (SELECT MIN(UTL_DTSTAMP)
                        FROM tbl_user_time_log C
                        WHERE C.USER_ID = A.USER_ID AND C.UTL_DTSTAMP > A.UTL_DTSTAMP)
   AND B.USER_ID = A.USER_ID

这意味着将仅使用属于同一用户的连续(按时间)行进行TIMESTAMPDIFF计算。

如果您使用的是MySQL 8+,则可以使用LEAD()并完全删除JOIN

...
TIMESTAMPDIFF(SECOND, A.UTL_DTSTAMP, LEAD(UTL_DTSTAMP) OVER (PARTITION BY USER_ID ORDER BY UTL_DTSTAMP)) AS UTL_DURATION
FROM   tbl_user_time_log A
WHERE  A.USER_ID = '465615'
...