2016-06-08 7 views
0

SQL Server 2008Wählen Sie Datensätze basierend auf einem Wert Spalte aus dem letzten Datensatz zu ändern

So habe ich eine Tabelle namens Staaten, und es hat Daten wie folgt aus:

DateTime    | skID | TZ | DomID | EventName | SKGrpID | State 
-------------------------------------------------------------------------- 
2016-06-08 09:22:54.010 | 1234 | 1 | 222 | 0   | 4321 | 0 
2016-06-08 09:22:54.000 | 1234 | 1 | 222 | 3   | 4321 | 3 
2016-06-08 09:21:56.000 | 1234 | 1 | 222 | 8   | 4321 | 4 
2016-06-08 09:19:00.000 | 1234 | 1 | 222 | 7   | 4321 | 4 
2016-06-08 09:18:58.000 | 1234 | 1 | 222 | 4   | 4321 | 4 
2016-06-08 09:13:06.000 | 1234 | 1 | 222 | 6   | 4321 | 6 
2016-06-08 09:10:42.000 | 1234 | 1 | 222 | 4   | 4321 | 4 
2016-06-08 09:10:40.000 | 1234 | 1 | 222 | 1   | 5555 | 1 
2016-06-08 09:00:28.003 | 1234 | 1 | 222 | 1   | 4321 | 1 

Reihen der Aufzeichnungen gedacht werden kann für jemanden, der ein Telefon beantwortet. Wenn der Zustand "4" ist, heißt das, dass sie am Telefon sprechen und wenn es etwas anderes ist, dann sind sie es nicht. Die ältesten Datensätze befinden sich am unteren Rand. Der dritte Datensatz um 9:10:42 ist der Beginn eines Anrufs und der Datensatz um 9:13:06 ist das Ende des Anrufs (Status von 4 auf 6 geändert).

Manchmal dauert der Anruf über mehrere Veranstaltungen. also auf den Rekord für 9:18:58 startet ein Anruf und es geht weiter bis zum Rekord um 9:21:56 (states start -> 4,4,4,3 < -Ende)

Ich hätte gerne eine Abfrage, die den Start- und Endsatz irgendwie auswählt, sie verbindet und eine Dauer bekommt. Das Problem ist, ich habe keine Ahnung, wie ich basierend auf dem Zustand von einer 4 auf etwas anderes wechseln kann. Ich kämpfe auch, um herauszufinden, wie man jeden Anfang jedes Anrufs auswählt (die Startdatensätze wären ein Datensatz mit einem Zustand von 4 und der vorhergehende Datensatz wäre etwas anderes (so wie Zustände 1, 4, 3, 6, 4) , 5 würden die zweiten und fünften Aufzeichnungen Anruf startet und 3 wäre und 6 würden die Enden der Anrufe werden.))

ideale Ergebnis wäre so etwas wie

StartTime, EndTime, Duration, skID, TZ, DomID, SKGrpID, StartEvent, StartState, EndEvent, EndState 

ich das bin in der Lage zu erreichen, Derzeit in Python nur durch Abfragen aller Zeilen und dann dicts und die Aufrufe auf diese Weise übereinstimmen, aber ich möchte so viel wie möglich in der SQL zu tun. Ist diese Art der Auswahl überhaupt möglich?

+0

Es ist möglich. Aber auf Stack Overflow sollten Sie zeigen, was Sie versucht haben. Aber um Ihnen einen Hinweis zu geben: Nachschlagen LIMIT 1 und ORDER BY ASC/DESC. Viel Glück. – user3741598

+0

@ user3741598 Ich kann posten, was ich versucht habe, aber das ist im Grunde eine Tonne kleiner Abfragen, die nichts haben, was ich will. Ich habe noch nie eine solche Frage gestellt und konnte nicht einmal einen guten Ausgangspunkt finden. Ich verstehe, wie Limit funktioniert, aber nicht, wie das hilft, wenn es mehrere Anrufe an einem Tag geben kann. – user5999614

+0

@ user3741598 Realisiert habe ich das falsche Tag. Dies ist SQL-Server, so dass ich nicht einmal Limit verwenden kann. – user5999614

Antwort

0
SELECT 'StartTime' 
    , 'EndTime' 
    , 'Duration' 
    , 'skID' 
    , 'TZ' 
    , 'DomID' 
    , 'SKGrpID' 
    , 'StartEvent' 
    , 'StartState' 
    , 'EndEvent' 
    , 'EndState'; 

Wenn das nicht ist, was Sie meinten, bitte klären. ;-)

+1

Ich habe nicht einmal Worte. – user5999614

1

Dies ist eine Möglichkeit, es zu tun:

select 
    max(case when RN = 1 then DateTime end) as StartTime, 
    max(case when RN = 2 then DateTime end) as EndTime, 
    max(case when RN = 1 then EventName end) as StartEvent, 
    max(case when RN = 2 then EventName end) as EndEvent 
from 
(
    select 
    *, 
    row_number() over (partition by CallId order by DateTime) as RN 
    from 
    (
    select 
     *, 
     sum(CallStatus) over (order by DateTime) as CallId 
    from 
    (
     select 
     * 
     from 
     (
     select 
      *, 
      lag(CallStatus) over (order by DateTime) as PrevCallStatus 
     from 
     (
      select 
      DateTime, 
      State, 
      EventName, 
      case when State = 4 then 1 else 0 end as CallStatus 
      from #Table1 
     ) A 
    ) B 
     where CallStatus != PrevCallStatus 
    ) C 
) D 
) E 
group by CallId 

Dies beginnt mit dem innersten abgeleitete Tabelle A die einen Anrufstatus 1/0 zuzuweisen verwendet wird. Die Tabelle B wird verwendet, um den vorherigen Wert von CallStatus abzurufen, mit dem dann Zeilen mit demselben CallStatus herausgefiltert werden. Da CallStatus 1/0 ist, kann es in einer laufenden Summe verwendet werden, um für jeden Anruf eine separate ID zu berechnen. Da die Daten von diesem immer 2 Zeilen enthalten, wird row_number verwendet, um den Zeilen eine Nummer zuzuordnen (1 = Start, 2 = Ende). Diese wird dann in der endgültigen Auswahl verwendet, um die Daten getrennt von Start- und Endzeilen zu erhalten.

Dies hat nicht alle Felder, aber zumindest sollte es Sie begonnen

:) erhalten

Dies vorausgesetzt, dass Sie immer eine End-Datensatz für Ihre Anrufe, und funktioniert nur in SQL Server 2012 oder höher. Für ältere Versionen müssen Sie etwas komplexeres für die laufende Summe und Verzögerung erstellen. Wahrscheinlich wäre dann ein Cursor die beste Option.

+0

Danke danke danke! Es ist leider SQL Server 2008 Version 10.5, also muss ich einen Weg finden, um vorbei zu kommen, nicht die Verzögerungsfunktion habend, aber das gab mir mindestens eine Idee, wie man darüber so weiter geht, danke wieder. – user5999614

Verwandte Themen