2016-08-03 52 views
1

我有一个具有以下字段自联接提取事件表中的相关记录?

Time     |  Status 
2016-01-21 16:11:00 |  Connected 
2016-01-21 16:51:00 |  Disconnected 
2016-01-21 17:01:00 |  Connected 
2016-01-21 17:10:00 |  Status X 
2016-01-21 17:20:00 |  Status Y 
2016-01-21 17:25:00 |  Disconnected 
2016-01-21 17:30:00 |  Connected 
2016-01-21 17:32:00 |  Disconnected 

我想要的输出是这样

Disconnected      Connected 
2016-01-21 16:51:00  |   2016-01-21 17:01:00 
2016-01-21 17:25:00  |   2016-01-21 17:30:00 
2016-01-21 17:32:00  | 

等的表。也就是说,我想,以显示与服务器断开连接时的数据。

我写这样

select B.Time, A.Time 
from (select Time 
     from table 
     where Status = 'Connected') as A, table B 
where B.Status = 'Disconnected' 
and B.Time < A.Time; 

我输出查询

Disconnected      Connected 
2016-01-21 16:51:00    2016-01-21 17:01:00 
2016-01-21 16:51:00    2016-01-21 17:30:00  

也就是说,我让所有的相关事件比它更大的每个断开连接的事件。不过,我想只不是每一行断开事件时,第一连接的事件。我能做什么?

回答

1

您可以通过断开时间组的输出,并使用分获得最早的:

SELECT B.Time, 
     min(A.Time) 
FROM 
    (SELECT TIME 
    FROM TABLE 
    WHERE Status = 'Connected') AS A, 
    TABLE B 
WHERE B.Status = 'Disconnected' 
    AND B.Time < A.Time 
GROUP BY 1 
; 

或无子查询:

SELECT tab1.`time`, 
     min(tab2.`time`) 
FROM tab1 AS tab1 
LEFT JOIN tab1 AS tab2 ON tab2.time > tab1.time 
WHERE tab1.Status = 'Disconnected' 
GROUP BY 1 
; 
3

的一个好方法是创建一个更复杂的ON包含所有时间逻辑的子句。 (http://sqlfiddle.com/#!9/81f61/5/0

select dis.Time as disconnected, con.Time as connected 
    from ev dis 
    join ev con ON con.Status = 'connected' 
       AND dis.Status = 'disconnected' 
       AND con.Time = (select MIN(Time) 
           from ev 
           where Status = 'connected' 
            and Time > dis.Time) 

这限制每行接合仅考虑第一MIN()连接时间的每个断开时间比晚。

如果你有大量的这些事件记录,考虑将在(Status, Time)的索引来优化这个查询。

0

我已经使用这个查询之前,它似乎运作良好

SELECT B.Time, A.Time 
FROM table 
WHERE NOT EXISTS (
    SELECT time 
    WHERE b.Time = a.Time 
    AND b.Disconnected > a.Connected 
)