0

所以我目前正在等待我的查询运行(大约需要 5 分钟)

我开发了一个查询,它将查看学生的出勤记录,识别一系列出勤代码并根据日期和上课时间对它们进行分组。

如果我试图找到特定学生的最高缺勤次数,则此查询非常有用,但当我尝试创建一个显示所有活跃学生的最高缺勤次数的表时,它变得更加棘手。

为此,我使用游标将 StudentNo(唯一 ID)分配给参数,然后运行我的原始查询,并将结果放入名为 @results 的临时表中。

这是我的代码:

DECLARE @StudentId INT
DECLARE @getStudentId CURSOR
DECLARE @Results TABLE(StudentNo INT,AttendanceCode VarChar(2),StartDate       DateTime,EndDate DateTime,"# of Classes" INT)
SET @getStudentId = CURSOR FOR
SELECT StudentNo
FROM [dbo].[Students]
OPEN @getStudentId
FETCH NEXT
FROM @getStudentId INTO @StudentId
WHILE @@FETCH_STATUS = 0
BEGIN

WITH AttendanceCodeMaster AS
(SELECT 
    [dbo].[Students].StudentNo,
    CAST(CONVERT(date,[dbo].[CourseOfferingSchedule].ClassDate,101) as DATETIME) + CAST(CONVERT(time,dbo.CourseOfferingSchedule.ClassStartTime,101) AS DATETIME) as ClassDate,
    [dbo].[CourseOfferingAttendanceScheduled].AttendanceCode

FROM [dbo].[CourseOfferingAttendanceScheduled]
    INNER JOIN [dbo].[Students] on [dbo].[CourseOfferingAttendanceScheduled].StudentNo = [dbo].[Students].StudentNo 
    INNER JOIN dbo.[CourseOfferingSchedule] on [dbo].[CourseOfferingAttendanceScheduled].ScheduleID =  [dbo].[CourseOfferingSchedule].ScheduleID
    INNER JOIN [dbo].[StudentStatus] on  [dbo].[Students].StudentStatusID =  [dbo].[StudentStatus].StudentStatusID

where 

[dbo].[Students].StudentNo = @StudentId and StudentStatus = 'Active' and Complete = 'Y' 

),

RunGroup AS
(SELECT StudentNo,ClassDate, AttendanceCode, (SELECT COUNT(*) From AttendanceCodeMaster as G WHERE G.AttendanceCode <> GR.AttendanceCode AND G.ClassDate <= GR.ClassDate) as RunGroup
FROM AttendanceCodeMaster as GR ),

AbsenceStreaks AS
(SELECT 
StudentNo,
AttendanceCode, 
MIN(ClassDate) as StartDate, 
MAX(ClassDate)as EndDate,
COUNT(*) as '# of Classes' 
FROM RunGroup
where AttendanceCode = 'A'
GROUP BY StudentNo,AttendanceCode, RunGroup),

LongestStreak AS
(SELECT TOP 1 * FROM AbsenceStreaks
Order BY '# of Classes' Desc)

INSERT INTO @Results SELECT * FROM LongestStreak

FETCH NEXT
FROM @getStudentId INTO @StudentId

END
CLOSE @getStudentId
DEALLOCATE @getStudentId

SELECT * from @Results
where "# of Classes" >= 30

order by StudentNo
4

1 回答 1

0

您不需要游标来解决此问题。以下可能对字段内容和名称做出了一些假设(因为很难遵循您的查询逻辑),但它应该为您提供正确的方法。

关键是可以通过枚举一个学生(在一个班级中)的所有上课天数,然后通过一个学生是否出席来枚举一个学生的所有上课天数来识别一串缺勤。对于一系列缺席或存在,这些值之间的差异是恒定的。

select studentNo, grp, AttendanceCode, count(*) as numInRow,
       min(ClassDate) as DateStart, max(ClassDate) as DateEnd
from (select acm.*
             (row_number() over (partition by StudentNo order by ClassDate) -
              row_number() over (partition by StudentNo, AttendanceCode order by ClassDate) 
             ) as grp
      from AttendanceCodeMaster acm
     ) acm
group by studentNo, grp, AttendanceCode;

(我不确定那里是否也有类代码。)

这应该为您提供您想要查找缺勤或在场序列的信息。

StudentNo,ClassDate, AttendanceCode, (SELECT COUNT(*) From AttendanceCodeMaster as G WHERE G.AttendanceCode <> GR.AttendanceCode AND G.ClassDate <= GR.ClassDate) as RunGroup FROM AttendanceCodeMaster

于 2013-08-16T18:01:15.983 回答