开发者

TSQL Counting number of Consecutive Absence in a row within time period

Problem: I'm trying to calculate the number of consecutive absence each student have for a particular class within a week period.

e.g. If class MATH1234 has classes on Day 1 Period 4 and Day 4 Period 3, and student 0012345 was absent for Day 1 Period 4 and Day 4 Period 3 in Week 1, it is the same as if that student was absent for Day 4 Period 3 in Week 1 and Day 1 Period 4 in Week 2.

I have a table called Lessons that contain a running list of all the students and the classes they are enrolled in and whether they were absent for any classes:

Lessons([Student ID], [Class Number], [Line Number], [Academic Period], [Year], [Term], [Week], [Day Period], [ClassDate], [IsAbsent], [ReasonCode], [ConsecutiveAbs])

I need to calculate the number of Consecutive Absence a student have for each class that they are enrolled in where the consecutive abs are within a period of one week (see explanation above).

Given that:

Student ID    Class Number    Line Number Academic Period Year    Term    Week    Day Period  ClassDate               IsAbsent    ReasonCode  ConsecutiveAbs
001234        1CVASX11        1           1               2011    1       3       1       2011-02-14 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       4       1       2011-02-21 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1  开发者_高级运维     4       2       2011-02-23 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       5       1       2011-02-28 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       5       2       2011-03-02 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       6       1       2011-03-07 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       6       2       2011-03-09 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       7       2       2011-03-16 00:00:00.000     1           U           0
001234        1CVASX11        1           1               2011    1       9       1       2011-03-28 00:00:00.000     1           U           0
001234        1CVASX61        6           1               2011    1       9       2       2011-03-28 00:00:00.000     1           U           0

The ConsecutiveAbs for student 001234 for Class Number 1CVASX11 on ClassDate 28/3 would be 1 as that previous absence to that date was the 16/3 which is more than a week ago. Likewise, the ConsecutiveAbs on ClassDate 9/3 would be 2 as that student was also absent on the 7/3 which is within the time period of one week.

What I am currently doing is Updating the Lessons table change the value of ConsecutiveAbs like this:

UPDATE Lessons
SET ConsecutiveAbs = 
(SELECT ISNULL(SUM(CAST(IsAbsent AS numeric)), 0)
 FROM Lessons AS L3
 WHERE L3.IsAbsent = 1
 AND L1.IsAbsent <> 0
 AND L3.[Student ID] = L1.[Student ID]
 AND L3.[Class Number] = L1.[Class Number]
 AND L3.[Line Number] = L1.[Line Number]
 AND L3.[Year] = L1.[Year]
 AND L3.[ClassDate] <= L1.[ClassDate]
 AND (L3.[ClassDate] > (SELECT MAX(L2.ClassDate)
      FROM Lessons AS L2
      WHERE L2.IsAbsent = 0
      AND L2.[Student ID] = L1.[Student ID]
      AND L2.[Class Number] = L1.[Class Number]
      AND L2.[Line Number] = L1.[Line Number]
      AND L2.[Year] = L1.[Year]
      AND L2.ClassDate < L1.[ClassDate]
 ) OR (SELECT MAX(L2.ClassDate)
       FROM Lessons AS L2
       WHERE L2.IsAbsent = 0
       AND L2.[Student ID] = L1.[Student ID]
       AND L2.[Class Number] = L1.[Class Number]
       AND L2.[Line Number] = L1.[Line Number]
       AND L2.[Year] = L1.[Year]
       AND L2.ClassDate < L1.[ClassDate]
 ) IS NULL))
 FROM Lessons AS L1

But that give me this:

001234  1CVASX11    1   1   2011    1   3   1   2011-02-14 00:00:00.000 1   U   1
001234  1CVASX11    1   1   2011    1   4   1   2011-02-21 00:00:00.000 1   U   2
001234  1CVASX11    1   1   2011    1   4   2   2011-02-23 00:00:00.000 1   U   3
001234  1CVASX11    1   1   2011    1   5   1   2011-02-28 00:00:00.000 1   U   4
001234  1CVASX11    1   1   2011    1   5   2   2011-03-02 00:00:00.000 1   U   5
001234  1CVASX11    1   1   2011    1   6   1   2011-03-07 00:00:00.000 1   U   6
001234  1CVASX11    1   1   2011    1   6   2   2011-03-09 00:00:00.000 1   U   7
001234  1CVASX11    1   1   2011    1   7   2   2011-03-16 00:00:00.000 1   U   8
001234  1CVASX11    1   1   2011    1   9   1   2011-03-28 00:00:00.000 1   U   9
001234  1CVASX61    6   1   2011    1   9   2   2011-03-28 00:00:00.000 1   U   9

I need to set a time period in there so it only add up within a week of the ClassDate. Anyone have any idea?


I think the one piece you're missing is limiting the count to only include an absence is if it is under 7 days of the original absence.

The following query includes that criteria, and I believe it gives they results you're looking for:

UPDATE LessonsAbsent
SET ConsecutiveAbs = (
    SELECT 
        ISNULL(SUM(CAST(IsAbsent AS numeric)), 0)
    FROM 
        Lessons RunningTotalAbsent 
    WHERE
        RunningTotalAbsent.IsAbsent = 1
        AND LessonsAbsent.[Student ID] = RunningTotalAbsent.[Student ID]
        AND LessonsAbsent.[Class Number] = RunningTotalAbsent.[Class Number]
        AND LessonsAbsent.[Line Number] = RunningTotalAbsent.[Line Number]
        AND LessonsAbsent.[Year] = RunningTotalAbsent.[Year]
        AND LessonsAbsent.ClassDate >= RunningTotalAbsent.ClassDate

        -- Only count as consecutive if the absence happened within under 7 days.
        AND DATEDIFF(DAY, RunningTotalAbsent.ClassDate, LessonsAbsent.ClassDate) < 7
    )
FROM Lessons LessonsAbsent 
WHERE LessonsAbsent.IsAbsent = 1
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜