我的数据如下。
id device state timestamp
250708 1004-3-007294 9 02/01/2019 9:20
250694 1004-3-007294 8 02/01/2019 9:31
250769 1004-3-007294 7 02/01/2019 10:04
250774 1004-3-007294 5 02/01/2019 10:13
250778 1004-3-007294 4 02/01/2019 10:20
250785 1004-3-007294 11 02/01/2019 10:27
250808 1004-3-007294 4 02/01/2019 10:29
250814 1004-3-007294 11 02/01/2019 10:36
250795 3091-5-007208 7 02/01/2019 10:39
250819 3091-5-007208 5 02/01/2019 10:42
250832 3091-5-007208 4 02/01/2019 10:58
250837 3091-5-007208 11 02/01/2019 11:02
250846 3091-5-007208 4 02/01/2019 11:13
当第一次设备状态从5更改为4时,我需要查找所有设备的时差,因为在我的数据库设备中,设备永远不会再回到状态5,而是将状态从4更改为11、11到4。请帮我写查询。
答案 0 :(得分:1)
您可以为此使用JOIN。以下假设存在一个正好是5-> 4的过渡,因此不必费心检查它是否是第一个过渡:
SELECT t1.id, t2.id, TIMESTAMPDIFF(SECOND, t1.timestamp,t2.timestamp) AS diff
FROM t AS t1
INNER JOIN t AS t2 ON t2.device = t1.device AND t2.state = 4 AND t2.timestamp > t1.timestamp
LEFT JOIN t AS tx ON t1.device = tx.device AND tx.timestamp > t1.timestamp AND tx.timestamp < t2.timestamp
WHERE t1.state = 5 AND tx.id IS NULL
上面的示例中的LEFT连接可确保仅匹配连续的过渡(例如250774与250778和250808连接,但后者将被丢弃)。
答案 1 :(得分:0)
SELECT A.Device, TIMESTAMPDIFF(SECOND,B.t2,A.t1) as differenceintime
FROM
( SELECT device, MIN(timestamp) as t1
FROM tableName
WHERE state = 5
GROUP BY device
) as A
INNER JOIN
( SELECT device, MIN(timestamp) as t2
FROM tableName
WHERE state = 4
GROUP BY device
) as B
ON A.Device = B.Device
答案 2 :(得分:0)
我认为您可以使用条件聚合:
select device,
timestampdiff(second,
min(case when status = 4 then timestamp end),
max(case when status = 5 then timestamp end)
) as diff_in_seconds
from t
group by device;
答案 3 :(得分:0)
如果您使用的是更高版本的MySQL,则可以使用LEAD
函数获取每一行的下一个状态
SELECT *,
LEAD(State) OVER(PARTITION BY device ORDER BY TimeStamp) AS NextState,
LEAD(TimeStamp) OVER(PARTITION BY device ORDER BY TimeStamp) AS NextTimeStamp
FROM t;
其中一台设备将提供:
id device state timestamp NextState NextTimeStamp
---------------------------------------------------------------------------------------------
250795 3091-5-007208 7 2019-02-01 10:39:00 5 2019-02-01 10:42:00
250819 3091-5-007208 5 2019-02-01 10:42:00 4 2019-02-01 10:58:00 <---
250832 3091-5-007208 4 2019-02-01 10:58:00 11 2019-02-01 11:02:00
250837 3091-5-007208 11 2019-02-01 11:02:00 4 2019-02-01 11:13:00
250846 3091-5-007208 4 2019-02-01 11:13:00 NULL NULL
这将使您能够确定状态从5变为4的时间。您只需要将上述查询放入子查询中,并应用where子句:
SELECT t.device,
t.TimeStamp AS ChangedToFive,
t.NextTimeStamp AS ChangedFromFiveToFour
FROM ( SELECT *,
LEAD(State) OVER(PARTITION BY device ORDER BY TimeStamp) AS NextState,
LEAD(TimeStamp) OVER(PARTITION BY device ORDER BY TimeStamp) AS NextTimeStamp
FROM t
) AS t
WHERE t.State = 5
AND t.NextState = 4;
如果您使用的旧版本不支持使用LEAD
,那么您将需要使用相关的子查询来复制功能:
SELECT t.device,
t.TimeStamp AS ChangedToFive,
t.NextTimeStamp AS ChangedFromFiveToFour
FROM ( SELECT *,
( SELECT TimeStamp
FROM t AS t2
WHERE t2.Device = t.Device
AND t2.TimeStamp > t.TimeStamp
ORDER BY TimeStamp
LIMIT 1
) AS NextTimeStamp
FROM t
WHERE t.State = 5
AND ( SELECT State
FROM t AS t2
WHERE t2.Device = t.Device
AND t2.TimeStamp > t.TimeStamp
ORDER BY TimeStamp
LIMIT 1
) = 4 -- next state = 4 to satisfy changing from 5 to 4
) AS t;