2016-08-03 8 views
1

Ich habe eine Tabelle, die die folgenden FelderSelf-Join, um verwandte Datensätze aus der Ereignistabelle zu extrahieren?

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 

ich die Ausgabe wie diese

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  | 

und so weiter sein wollen hat. Das heißt, ich möchte die Daten für den Server getrennt anzeigen.

ich geschrieben habe eine Abfrage wie diese

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; 

Meine Ausgabe ist

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  

, dass für jedes nicht verbundene Ereignis erhalte ich alle verbundenen Ereignisse größer ist als es. Ich möchte jedoch nur das erste verbundene Ereignis größer als das getrennte Ereignis für jede Zeile. Was kann ich tun?

Antwort

1

Sie können Gruppe die Ausgabe von Trennzeit und benutzen min die früheste zu bekommen:

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 
; 

oder ohne Unterabfrage:

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

Ein guter Ansatz, um dies eine komplexere zu schaffen ON Klausel, die die gesamte Zeitlogik enthält. (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) 

Dies schränkt jede Reihe verbunden werden nur die erste MIN() Verbindungszeit später als jede disconnect Zeit zu berücksichtigen.

Wenn Sie eine große Anzahl dieser Ereignisdatensätze haben, sollten Sie einen Index auf (Status, Time) platzieren, um diese Abfrage zu optimieren.

0

Ich habe diese Abfrage vor und es scheint gut genutzt

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