SQL server: search nach aufeinanderfolgenden Abwesenheit zählt für Studenten über benutzerdefinierte Termine

Ich habe einen Tisch, der die Teilnahme der Schüler für jeden Tag speichert. Ich muss Studenten bekommen, die nacheinander 3 Tage lang abwesend sind. Allerdings sind die Termine, wenn die Teilnahme genommen wird, nicht in einer Reihenfolge, einige Tage wie Befreiung, Feiertage, Wochenenden sind ausgeschlossen. Die Termine, an denen die Kursteilnehmer teilnahmen, sind die data, in denen die datasätze in dieser Tabelle vorhanden sind.

Die data sind wie

StudentId Date Attendance ----------------------------------------- 178234 1/1/2017 P 178234 5/1/2107 A 178234 6/1/2107 A 178234 11/1/2107 A 178432 1/1/2107 P 178432 5/1/2107 A 178432 6/1/2107 P 178432 11/1/2107 A 

Im obigen Fall sollte das Ergebnis sein

 StudentId AbsenceStartDate AbsenceEndDate ConsecutiveAbsences ---------------------------------------------------------------------------- 178234 5/1/2017 11/1/2017 3 

Ich habe versucht, diese Lösung zu implementieren, um aufeinanderfolgende Abwesenheiten in SQL zu berechnen. Das hat aber nur für Termine gearbeitet. Irgendwelche Vorschläge werden großartig sein, danke

Oh, du hast beide Abwesenheiten und Geschenke in der Tabelle. Sie können den Unterschied von row_numbers() -Ansatz verwenden:

 select studentid, min(date), max(date) from (select a.*, row_number() over (partition by studentid order by date) as seqnum, row_number() over (partition by studentid, attendance order by date) as seqnum_a from attendance a ) a where attendance = 'A' group by studentid, (seqnum - seqnum_a) having count(*) >= 3; 

Der Unterschied der Zeilennummern erhält aufeinanderfolgende Werte, die gleich sind. Dies ist ein wenig schwierig zu verstehen, aber wenn Sie die Unterabfrage laufen, sollten Sie sehen, wie der Unterschied ist konstant für aufeinander folgende Abwesenheiten oder Geschenke. Sie kümmern sich nur um Abwesenheiten, also die where in der äußeren Abfrage.

Versuche dies:

 declare @t table (sid int, d date, att char(1)) insert @t (sid,d, att) values (178234, '1/1/2017','P'), (178234, '5/1/2017','A'), (178234, '6/1/2017','A'), (178234, '11/1/2017','A'), (178432, '1/1/2017','P'), (178432, '5/1/2017','A'), (178432, '6/1/2017','P'), (178432, '11/1/2017','A') Select s.sid, Min(sd) startDt, Max(ed) endDt, s.att, e.att, count(*) from @ts join @te on ed <= (select max(d) from @tm Where sid = s.sid and d > sd and att = 'A' and not exists (Select * from @t where sid = s.sid and d between sd and md and att = 'P')) Where s.att = 'A' and sd = (Select Min(d) from @t Where sid = s.sid and d < ed and att = 'A') group by s.sid, sd, s.att, e.att 

Das ist auch schwierig zu erklären: Grundsätzlich verbindet es sich mit dem Aliase s (für den Anfang) und e (für das Ende), wo die s-reihe die erste reihe in einer Reihe von zusammenhängenden absenzen ist, und die e. Zeilen sind alle folgenden Abwesenheiten, die vor dem nächsten date sind, an dem der Bolzen vorhanden ist. Dies erzeugt einen Satz von all dem 'A', die keine P-Zeile in ihnen haben. Dann die Sql-Gruppen durch die entsprechenden Werte, um das früheste und letzte date und die Anzahl der Zeilen in jeder Gruppe zurückzugeben.
Die letzte where-Klausel stellt sicher, dass die s-Zeile die erste Zeile in der Gruppe ist.