2016-12-12 3 views
0

So eine Tabelle Ich habe mit dieser Grundstruktur bekam (ich habe versucht, nicht relevante Felder zu eliminieren):MySQL - Wählen Sie Erste/Letzte Verschiedene Reihe

EmpID EventDate Timestamp   State State_Time 
1111 2016-12-01 2016-12-01 00:00:00 a  01:00:00 
1111 2016-12-01 2016-12-01 01:00:00 a  01:00:00 
1111 2016-12-01 2016-12-01 02:00:00 a  01:00:00 
1111 2016-12-01 2016-12-01 03:00:00 a  01:00:00 
1111 2016-12-01 2016-12-01 04:00:00 a  00:24:00 
1111 2016-12-01 2016-12-01 04:24:00 b  00:03:00  1* 
1111 2016-12-01 2016-12-01 04:27:00 c  00:33:00  2* 
1111 2016-12-01 2016-12-01 05:00:00 c  01:00:00 
1111 2016-12-01 2016-12-01 06:00:00 c  01:00:00 
2222 2016-12-01 2016-12-01 10:21:00 c  00:03:00 
2222 2016-12-01 2016-12-01 10:24:00 a  00:10:00 
2222 2016-12-01 2016-12-01 10:34:00 b  00:15:00 
3333 2016-12-01 2016-12-01 00:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 01:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 02:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 03:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 04:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 05:00:00 c  01:00:00 
3333 2016-12-01 2016-12-01 06:00:00 c  00:21:00 
3333 2016-12-01 2016-12-01 06:21:00 a  00:03:00  1* 
3333 2016-12-01 2016-12-01 06:24:00 b  00:36:00  2* 
3333 2016-12-01 2016-12-01 07:00:00 b  01:00:00 
3333 2016-12-01 2016-12-01 08:00:00 b  01:00:00 

Ich muss in der Lage sein, bestimmte Arten zu ziehen zwei von Zeilen (mit separaten Abfragen ist in Ordnung/vorzuziehen).

  1. Der Status ändert sich, aber EmpID und EventDate bleiben gleich (wie die vorherige Zeile).
  2. Der erste Datensatz einer Serie, bei der sich der Status für das verbleibende EventDate nicht ändert (mit konstanter EmpID und State).

Ich habe * hinzugefügt, um anzugeben, nach denen ich suche. Während dieser Datensatz nur ein Datum enthält, enthält die eigentliche Quelle Daten, die sich über ein Jahr erstrecken und weiter wachsen.

Vielen Dank für Ihre Unterstützung!

+0

Und warum wollen Sie nicht die "2222" Datensätze? –

+0

Die aufeinanderfolgenden Datensätze weisen auf einen Fehler hin - ich muss diese markieren und feststellen, wann der Fehler gestartet (Abfrage 2) oder beendet wurde (Abfrage 1). In diesem Fall hatte 2222 keine Fehler. – Jake

+0

Wählen Sie aus 'tablename' als linken Join 'Tabellenname' als b on .... Sie können in der gleichen Tabelle beitreten, um zu bekommen, was Sie wollen. Jetzt würde ich diesen Tisch lieber normalisieren, aber – user3802077

Antwort

0

Ihre Regeln für (1) wählen Sie mehr Zeilen als Sie mit der 1 * markiert. Der eine von 4:27 zum Beispiel.

Hier query (1):

SELECT a.* 
FROM tab as a 
JOIN tab as b 
WHERE a.EmpID = b.EmpID 
    AND a.EventDate = b.EventDate 
    AND a.State <> b.State 
    AND b.TimeStamp = (SELECT max(Timestamp) 
        FROM tab WHERE TimeStamp < a.TimeStamp); 

Und hier ist Abfrage (2). Es läuft eine Weile.

SELECT a.* 
    FROM tab as a 
    WHERE (NOT EXISTS 
    (SELECT * FROM tab as b 
     WHERE a.EmpID = b.EmpID 
       AND a.EventDate = b.EventDate 
       AND a.State = b.State 
       AND b.Timestamp < a.Timestamp)) 
    AND (NOT EXISTS 
    (SELECT * FROM tab as b 
     WHERE a.EmpID = b.EmpID 
      AND a.EventDate = b.EventDate 
      AND a.State<> b.State 
      AND b.Timestamp > a.Timestamp)) 
    AND (EXISTS 
    (SELECT * FROM tab as b 
     WHERE a.EmpID = b.EmpID 
      AND a.EventDate = b.EventDate 
      AND a.State = b.State 
      AND b.Timestamp > a.Timestamp)) 

Die drei Stücke von WHERE in Abfrage 2: 1. sicherstellen, dass es für gleiche emp, Datum und Zustand keine vorherige Rekord. 2. Stellen Sie sicher, dass kein zukünftiger Datensatz für dasselbe Emp und Datum mit einem anderen Status vorhanden ist. 3. Stellen Sie sicher, dass mindestens ein zukünftiger Datensatz für dasselbe emp, date und state (in der Reihenfolge der Wörter, dass eine Kette tatsächlich gestartet wurde) vorhanden ist.