2013-08-16 17 views
0
的更好的辦法

所以我目前正在等待我的查詢運行(約需5分鐘)檢測的連續記錄數了很多不同的用戶ID的唯一

我開發了一個查詢,將看在學生的出勤記錄中,識別出一批考勤代碼並根據日期和上課時間對其進行分組。

如果我試圖找到某個特定學生缺勤的最高數量,但是當我嘗試創建一個顯示所有在校學生缺勤情況最高的表格時,這個查詢效果很好。

爲了實現這一點,我使用遊標將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 
+3

什麼是你的問題究竟? – WendiKidd

+0

提示1:使用別名和縮進來使代碼更易於閱讀。 –

+0

注意!謝謝! –

回答

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爲G WHERE G.AttendanceCode <> GR.AttendanceCode和G.ClassDate < = GR.ClassDate)作爲RunGroup FROM AttendanceCodeMaster

+0

哇,這比我之前的做法快得多,謝謝!我上週也在休假,否則我會早些時候感謝你! –