mysql - MySQL 总时间正在增加
问题描述
我有这个疑问,
SELECT
testTimes.reportId,
testTimes.userID,
-- diff,
SUM(diff) AS total
FROM
(
SELECT
start_log.reportID,
start_log.userID,
start_log.testID,
MAX(start_log.eventDateTime) AS start_time,
end_log.eventDateTime AS end_time,
TIMESTAMPDIFF(MINUTE,
MAX(start_log.eventDateTime),
end_log.eventDateTime) AS diff
FROM
testtracker_event AS start_log
INNER JOIN testtracker_event AS end_log ON
( start_log.userID = end_log.userID
AND start_log.reportID = end_log.reportID
AND start_log.testID = end_log.testID
AND end_log.eventDateTime > start_log.eventDateTime)
WHERE
(start_log.eventType = 'start'
OR start_log.eventType = 'resume')
AND (end_log.eventType = 'finish'
OR end_log.eventType = 'pause')
AND start_log.reportID = '20466'
GROUP BY
start_log.userID,
start_log.testID,
start_log.eventDateTime,
start_log.reportID
ORDER BY
start_time DESC) testTimes
当针对该数据集运行时;
|reportID|testID|eventDateTime|userID|eventType|workstation|note|
|--------|------|-------------|------|---------|-----------|----|
|20466|1|2018-04-26 14:41:42|msharpe|start| | |
|20466|1|2018-04-26 15:17:10|msharpe|finish| | |
|20466|1|2018-04-26 15:17:20|msharpe|reset| |"MIS-CLICK"|
|20466|1|2018-04-26 15:17:21|msharpe|start| | |
|20466|1|2018-04-27 08:11:02|msharpe|finish| | |
|20466|2|2018-04-26 14:41:43|msharpe|start| | |
|20466|2|2018-04-27 08:11:02|msharpe|finish| | |
|20466|3|2018-04-26 14:42:15|msharpe|start| | |
|20466|3|2018-04-26 15:17:23|msharpe|finish| | |
|20466|4|2018-04-26 15:19:25|msharpe|start| | |
|20466|4|2018-04-26 15:34:59|msharpe|finish| | |
|20466|5|2018-04-26 14:42:21|msharpe|start| | |
|20466|5|2018-04-26 15:17:29|msharpe|finish| | |
|20466|7|2018-04-26 16:32:57|msharpe|start| | |
|20466|7|2018-04-27 08:11:03|msharpe|finish| | |
|20466|8|2018-04-26 15:38:29|msharpe|markna| | |
|20466|10|2018-04-27 12:05:21|msharpe|start| | |
|20466|10|2018-04-27 12:05:22|msharpe|finish| | |
|20466|16|2018-04-26 14:42:17|msharpe|start| | |
|20466|16|2018-04-26 15:17:28|msharpe|finish| | |
|20466|40|2018-04-26 14:42:17|msharpe|start| | |
|20466|40|2018-04-26 15:17:26|msharpe|finish| | |
|20466|50|2018-04-27 12:05:22|msharpe|start| | |
|20466|50|2018-04-27 12:05:23|msharpe|finish| | |
|20466|52|2018-04-27 08:50:54|msharpe|start| | |
|20466|52|2018-04-27 10:00:27|msharpe|finish| | |
|20466|53|2018-04-26 15:58:56|msharpe|start| | |
|20466|53|2018-04-26 16:32:56|msharpe|finish| | |
|20466|54|2018-04-26 15:38:24|msharpe|markna| | |
RESULT - 20466 msharpe 3293
结果,我目前得到了 3,293 分钟,即使有并发调度和 2 个看起来像是在一夜之间签署了偶数的情况,我预计结果会非常大约 1845
我可以看到发生了一些重复,我猜这与join
我缺乏获得正确答案的经验或知识有关,在这种情况下,我找到的答案,我很难与这种情况相关联。
虽然我知道有些人可能会想引用我的一个较旧的问题 How would I update this MySQL query to get total elapsed time from start, stop, pause and resume events and this question Calculating Difference on datetime row betwen rows on the same table 作为重复项,我要问的是改进现有查询以不产生复合效果,和/或尽量减少重复。
SQLFiddle 很好的衡量标准,http: //www.sqlfiddle.com/#!9/0dd34d/1
解决方案
在您现有的连接中,您将每个起点与多个终点相匹配,因此您将总数相乘。您需要将每个起点与下一个终点相匹配(一个起点,一个终点)。除非您正在运行支持的数据库版本,否则您lead() over()
可以使用相关子查询来实现这一点,如下所示:
SELECT
start_log.reportID
, start_log.userID
, start_log.testID
, start_log.eventDateTime AS start_time
, start_log.end_time
, TIMESTAMPDIFF(MINUTE,start_log.eventDateTime,start_log.end_time) AS diff
FROM (
select
s.*
, (select f.eventDateTime from mytable f
WHERE s.userID = f.userID
AND s.reportID = f.reportID
AND s.testID = f.testID
AND f.eventType = 'finish'
AND f.eventDateTime > s.eventDateTime
order by f.eventDateTime
limit 1
) end_time
from mytable as s
where s.eventType = 'start'
) AS start_log
该查询的结果(使用提供的示例)是:
reportID userID testID start_time end_time diff
---- ---------- --------- -------- --------------------- --------------------- ------
1 20466 msharpe 1 26.04.2018 14:41:42 26.04.2018 15:17:10 35
2 20466 msharpe 1 26.04.2018 15:17:21 27.04.2018 08:11:02 1013
3 20466 msharpe 2 26.04.2018 14:41:43 27.04.2018 08:11:02 1049
4 20466 msharpe 3 26.04.2018 14:42:15 26.04.2018 15:17:23 35
5 20466 msharpe 4 26.04.2018 15:19:25 26.04.2018 15:34:59 15
6 20466 msharpe 5 26.04.2018 14:42:21 26.04.2018 15:17:29 35
7 20466 msharpe 7 26.04.2018 16:32:57 27.04.2018 08:11:03 938
8 20466 msharpe 10 27.04.2018 12:05:21 27.04.2018 12:05:22 0
9 20466 msharpe 16 26.04.2018 14:42:17 26.04.2018 15:17:28 35
10 20466 msharpe 40 26.04.2018 14:42:17 26.04.2018 15:17:26 35
11 20466 msharpe 50 27.04.2018 12:05:22 27.04.2018 12:05:23 0
12 20466 msharpe 52 27.04.2018 08:50:54 27.04.2018 10:00:27 69
13 20466 msharpe 53 26.04.2018 15:58:56 26.04.2018 16:32:56 34
虽然可能需要进一步改进,但这应该可以让您继续前进。
推荐阅读
- php - PHP中POST Sanitation和Prepared语句之间的区别
- scala - Scala Left Join 返回 Full Join 的结果
- angular - forkJoin 上的 takeUntil 是否会调用 forkJoined observables 上的函数?
- vuepress - 只有我通过纱线尝试时,Vuepress 开发服务器无法正常工作
- javascript - 如何使用 Jquery 获取添加的输入字段的值?
- python - 如何从 Python 发送 AMP 电子邮件?它在技术上与普通电子邮件有何不同
- ios - 将 httpBody 转换为 x-www-urlencoded
- sql - SAS 通过在 SQL 中处理,添加一个计数器
- gradle - 将 kapt 与多平台子项目一起使用
- python-2.7 - 获取'ClientError:调用HeadObject操作时发生错误(403):Forbidden'同时使用boto3进行文件的跨帐户复制