I just need advice on how I could speed up my code. I'm supposed to count on yearly base, how the grades of some students are improving and calculate in percentage. Also keep in mind that I have around 100k-150k records per year.
Basically end results look like this, so at end of 20150131, 2% of students had grade A finished with grade B and so on.
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%
Input looks like this .. just info about student and his grade on certain date
Student Date Grade
1 20150131 A
2 20150131 C
3 20150131 A
1 20140131 B
2 20140131 B
3 20140131 A
My code looks like this:
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
I understand SQL Server doesn't like while loops, as I understand it kills it's performance... But I'm using while inside of while loop... going over years, for each grade and just counting them and... first I insert 1 row of current grade, and then I keep updating that row until its fully populated.
I do understand this is really bad, but at the end that's why I am here to learn better way to accomplish this.
Thank you in advance!
GROUP BYand subqueries.