2016-08-03 51 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 
)