2015-10-07 111 views
1

我只需要關於如何加快我的代碼的建議。我應該指望每年的基數,一些學生的成績如何提高並以百分比計算。另外請記住,我每年有大約10萬-15萬條記錄。While循環的SQL Server性能問題

基本上最終的結果看起來像這樣,所以在20150131年底,2%的學生已經達到了A級,並且達到了B級,等等。

Grade Date  B C 
    A  20150131 2% 3% 
    B  20150131 88% 85% 
    C  20150131 10% 12% 
    A  20140131 2% 3% 
    B  20140131 88% 85% 
    C  20140131 10% 12% 
    A  20130131 2% 3% 
    B  20130131 88% 85% 
    C  20130131 10% 12% 

輸入看起來是這樣的。關於學生只是信息以及他對某些日期評分

Student Date Grade 
    1  20150131 A 
    2  20150131 C 
    3  20150131 A 
    1  20140131 B 
    2  20140131 B 
    3  20140131 A 

我的代碼如下所示:

WHILE @StartDateInt > @PeriodSpan 
BEGIN 
while @y <= @CategoriesCount 
BEGIN 

    set @CurrentGr = (Select Grade from #Categories where RowID = @y) 
    set @CurrentGrCount = (Select COUNT(Students) from #TempTable where Period = @PeriodSpan and Grade = @CurrentGr)  
    set @DefaultCurrentGr = (Select Grade from #Categories where RowID = @y) 

    insert into Grade_MTRX (Student, Period, Grades_B, SessionID)    
    select temp1.Grade, @PeriodNextSpan as Period, COUNT(Grades_B)/@CurrentGrCount as 'Grades_B', @SessionID    
    from #TempTable temp1 
    join #TempTable temp2 on temp1.Student = temp2.Student and temp1.Period + 10000 = temp2.Period 
    where temp1.Grade = @CurrentGr and temp2.Grade = 'C' and temp1.Period = @PeriodSpan  
    group by temp1.Grade, temp1.Period 

    update Grade_MTRX set Grades_C = (
    select COUNT(Grades_C)/@CurrentGrCount 
    from #TempTable 
    where Grade = 'C' and Period = @PeriodNextSpan) 
    where Category = @CurrentGr and Period = @PeriodNextSpan 

end 
end 

我瞭解SQL Server不像while循環,據我瞭解它會殺死它的性能......但我在while循環內使用while ......歷經多年,因爲每個年級,並只計算他們和...首先,我插入當前成績的1行,然後我不斷更新該行,直到其完全填充。

我明白這確實很糟糕,但最終這就是爲什麼我在這裏學習更好的方法來實現這一目標。

預先感謝您!

+0

分享輸入和期望的輸出,你將得到沒有循環的答案 – lad2025

+0

你應該瞭解'GROUP BY'和子查詢。 – 2015-10-07 07:40:16

+0

你將只有A,B和C等級? –

回答

1

每年150,000條記錄真的沒什麼。比方說,你有這個成績表:

CREATE TABLE Grade(
student_id INT, 
date INT, 
grade CHAR); 

有了這個信息:

student_id date grade 
    1  2013 A 
    1  2014 A 
    1  2015 B 
    2  2013 B 
    2  2014 A 
    2  2015 C 
    3  2013 C 
    3  2014 A 
    3  2015 B 

然後,如果你只是運行像一個查詢:

SELECT this_year.date, last_year.grade AS last_year, this_year.grade AS this_year, COUNT(*) AS total, 
(100.0 * COUNT(*))/(SELECT COUNT(*) FROM Grade WHERE date = this_year.date) AS percent 
FROM Grade AS this_year 
    INNER JOIN Grade AS last_year ON this_year.date = last_year.date + 1 
    AND this_year.student_id = last_year.student_id 
GROUP BY this_year.date, this_year.grade, last_year.grade 
ORDER BY 1, 2, 3; 

你結束了這些結果:

date | last_year | this_year | total |  percent  
------+-----------+-----------+-------+--------------------- 
2014 | A   | A   |  1 | 33.3333333333333333 
2014 | B   | A   |  1 | 33.3333333333333333 
2014 | C   | A   |  1 | 33.3333333333333333 
2015 | A   | B   |  2 | 66.6666666666666667 
2015 | A   | C   |  1 | 33.3333333333333333 
(5 rows) 

有幾毫米在使用這種查詢的數據行上不應該有任何真正的麻煩。甚至數千萬行。但是,如果您需要更快的速度,那麼請查看您可以使用Postgres,Oracle和MSSQL服務器執行的窗口功能。

+0

謝謝你指點我朝着正確的方向! – Veljko89