我必须找到时间,该表基于系统的代码为100时已过去,所以首先我认为我必须找到xID组的最新行,然后检查前一行,如果它们的代码是100,那么如果要这样做,我必须继续上一行直到它得到200的值,之后,它才从下一行200开始查找到现在的时间(值100)。
ID xID createdDate CODE
1 '1', '2019-07-27 11:52:01', '100'
2 '1', '2019-07-27 11:54:01', '200'
3 '2', '2019-09-03 05:10:02', '200'
4 '2', '2019-09-03 05:12:02', '200'
5 '3', '2019-09-02 05:12:02', '200'
6 '3', '2019-09-02 05:12:02', '100'
7 '3', '2019-09-02 05:12:02', '200'
8 '4', '2019-09-02 05:13:02', '200'
9 '5', '2019-09-03 05:10:03', '200'
10 '6', '2018-12-13 05:03:02', '200'
因此,此查询必须为每个xID组找到系统到目前为止使用代码100的总时间。希望我已经清楚了。这是到目前为止的sql。
select id, createdDate, code
from wlogs
where id in (
select max(id)
from wlogs
group by xid
)
order by xid;
编辑: MYSQL版本8.0 对于每种类型的xID,结果必须是这样的,其中totTimeWithCode100列必须以秒或分钟为单位显示时间无关紧要。
xID totTimeWithCode100
'1', '500'
'2', '2'
'3', '33'
'4', '200'
'5', '40'
'6', '200'
答案 0 :(得分:0)
在MySQL 8.0之前,我们可以在精心设计的SQL中使用用户定义的变量(以不受支持的方式),该变量利用了可重复观察但不能保证的行为。 (《 MySQL参考手册》特别警告用户定义变量的用法。)
类似这样的东西:
SELECT s.xid AS `xID`
, IFNULL(SUM(s.secs_in_code100),0) AS `totTimeWithCode100`
FROM (
SELECT IF(@prev_xid = t.xid AND @prev_code = 100, TIMESTAMPDIFF(SECOND,@prev_date,t.createddate),0) AS secs_in_code100
, @prev_xid := t.xid AS xid
, @prev_date := t.createddate AS createddate
, @prev_code := t.code AS code
FROM ( SELECT @prev_xid := ''
, @prev_date := '1970-01-02 03:00'
, @prev_code := ''
) i
CROSS
JOIN wlogs t
ORDER
BY t.xid
, t.createddate
) s
GROUP BY s.xid
ORDER BY s.xid
在MySQL 8.0中,我们可以通过使用分析/窗口函数来避免用户定义的变量。
答案 1 :(得分:0)
通过找到给定CODE = 100
的所有带有xID
的行,然后立即(按时间)紧跟着CODE != 100
的行,可以得到想要的结果。这可以通过LEFT JOIN
将带有CODE != 100
的行添加到前一行 来进行,如果该行具有CODE = 100
:
SELECT w.xID, COALESCE(SUM(TIMESTAMPDIFF(SECOND, w1.createdDate, w2.createdDate)), 0) AS totTimeWithCode100
FROM (SELECT DISTINCT xID FROM wlogs) w
LEFT JOIN (SELECT *
FROM wlogs
WHERE CODE = 100) w1 ON w1.xID = w.xID
LEFT JOIN wlogs w2 ON w2.xID = w1.xID
AND w2.createdDate = (SELECT MIN(createdDate)
FROM wlogs w3
WHERE w3.xID = w1.xID AND
w3.createdDate > w1.createdDate)
GROUP BY w.xID
ORDER BY w.xID;