残念ながら、mysql は Windows の機能をサポートしていません。これは、row_number() またはより良い累積合計 (Oracle でサポートされている) を使用すると、はるかに簡単になります。
解決策を説明します。テーブルに 2 つの追加の列があるとします。
- ClassSeqNum -- 1 から始まり、クラスの日付ごとに 1 ずつ増加するシーケンス。
- AbsentSeqNum -- 生徒がクラスを欠席するたびに 1 から始まり、その後欠席するたびに 1 ずつ増加するシーケンス。
重要な観察結果は、これら 2 つの値の差は、連続して欠席する場合は一定であるということです。mysql を使用しているため、これらの列をテーブルに追加することを検討してください。クエリに追加するのは非常に難しいため、この回答は非常に長くなります。
重要な観察結果を考えると、質問に対する答えは次のクエリによって提供されます。
select studentid, subjectid, absenceid, count(*) as cnt
from (select a.*, (ClassSeqNum - AbsentSeqNum) as absenceid
from Attendance a
) a
group by studentid, subjectid, absenceid
having count(*) > 2
(わかりました、これは各科目の学生の欠席のすべてのシーケンスを示しますが、これを学生のリストだけに絞り込む方法を理解できると思います。)
シーケンス番号はどのように割り当てますか? mysql では、自己結合を行う必要があります。したがって、以下は ClassSeqNum を追加します。
select a.StudentId, a.SubjectId, count(*) as ClassSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
group by a.StudentId, a.SubjectId
そして、次の例では欠勤シーケンス番号を追加します。
select a.StudentId, a.SubjectId, count(*) as AbsenceSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= a1.classDate
where AttendanceStatus = 0
group by a.StudentId, a.SubjectId
したがって、最終的なクエリは次のようになります。
with cs as (
select a.StudentId, a.SubjectId, count(*) as ClassSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
group by a.StudentId, a.SubjectId
),
a as (
select a.StudentId, a.SubjectId, count(*) as AbsenceSeqNum
from Attendance a join
Attendance a1
on a.studentid = a1.studentid and a.SubjectId = a1.Subjectid and
a.ClassDate >= s1.classDate
where AttendanceStatus = 0
group by a.StudentId, a.SubjectId
)
select studentid, subjectid, absenceid, count(*) as cnt
from (select cs.studentid, cs.subjectid,
(cs.ClassSeqNum - a.AbsentSeqNum) as absenceid
from cs join
a
on cs.studentid = a.studentid and cs.subjectid = as.subjectid
) a
group by studentid, subjectid, absenceid
having count(*) > 2