这应该可以解决问题:
growth
使用以下查询计算列
SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM (
SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
GROUP BY Student_ID,type
) od ON si=Student_ID AND ty=type AND cylast>test_date
GROUP BY si,ty, cylast
) getlast2
INNER JOIN ondemand la ON la.Student_Id=si AND la.type=ty AND la.test_date=cylast
INNER JOIN ondemand pr ON pr.Student_Id=si AND pr.type=ty AND pr.test_date=cyprev
然后将LEFT JOIN
其用于您的整体查询(此处略有简化版本):
SET @subj:="Numeracy";
SELECT Student_id,
SUM(If(ondemand.cycle="Feb7" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr7 Feb`,
SUM(If(ondemand.cycle="Jul7" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr7 July`,
SUM(If(ondemand.cycle="Feb8" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr8 Feb`,
SUM(If(ondemand.cycle="Jul8" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr8 July`,
SUM(If(ondemand.cycle="Feb9" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr9 Feb`,
SUM(If(ondemand.cycle="Jul9" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr9 July`,
SUM(If(ondemand.cycle="Feb10" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr10 Feb`,
SUM(If(ondemand.cycle="Jul10" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr10 Aug`,
growth
FROM ondemand LEFT JOIN (
SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM (
SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
GROUP BY Student_ID,type
) od ON si=Student_ID AND ty=type AND cylast>test_date
GROUP BY si,ty, cylast
) getlast2
INNER JOIN ondemand la ON la.Student_Id=si AND la.type=ty AND la.test_date=cylast
INNER JOIN ondemand pr ON pr.Student_Id=si AND pr.type=ty AND pr.test_date=cyprev
) gt ON si=Student_id AND ty=@subj
GROUP BY Student_id;
我省略了JOIN
表student
和ttstudent
它们的列的 s
ttstudent.ttstudentid,
ttstudent.studentid,
ttstudent.subjectid,
ttstudent.classnumber,
ttstudent.classid,
concat(student.fn, " ", student.sn) AS Student
编辑:
Just made the changes using your test_date
column. The subquery was tested in MySQL, I hope it also works in your database.
Edit2:
I slowly see where you are coming from. It's getting more and more complicated (just filled in the xtra conditions concerning type="Numeracy"
... Maybe there is an easier solution after all?
Anyway, here is a SQLfiddle to demonstrate the whole thing (and here a modified version: sqlfiddle2).
3rd and final edit:
What you probably want is something on the lines of SQLfiddle3 (--> only one SELECT command without a preceding SET
statement). Your complete command should then look something like this:
SELECT
ttstudent.ttstudentid,
ttstudent.studentid,
ttstudent.subjectid,
ttstudent.classnumber,
ttstudent.classid,
concat(student.fn, " ", student.sn) AS Student,
SUM(If(ondemand.cycle="Feb7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 Feb`,
SUM(If(ondemand.cycle="Jul7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 July`,
SUM(If(ondemand.cycle="Feb8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 Feb`,
SUM(If(ondemand.cycle="Jul8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 July`,
SUM(If(ondemand.cycle="Feb9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 Feb`,
SUM(If(ondemand.cycle="Jul9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 July`,
SUM(If(ondemand.cycle="Feb10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Feb`,
SUM(If(ondemand.cycle="Jul10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Aug`,
ondemand.Student_ID,
getdif.growth
FROM ttstudent
INNER JOIN student ON ttstudent.studentid = student.code
INNER JOIN ondemand ON ttstudent.studentid = ondemand.Student_ID
LEFT JOIN (
SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM (
SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
GROUP BY Student_ID,type
) od ON si=Student_ID AND ty=type AND cylast>test_date
GROUP BY si,ty, cylast
) getlast2
INNER JOIN ondemand la ON la.Student_ID=si AND la.type=ty AND la.test_date=cylast
INNER JOIN ondemand pr ON pr.Student_ID=si AND pr.type=ty AND pr.test_date=cyprev
) getdif ON si=ondemand.Student_ID AND ty=ondemand.type
WHERE ondemand.type='Numeracy'
GROUP BY ondemand.Student_ID
My previous versions reflected my personal preference of avoiding any kind of redundancy and also my ambition to parameterize things as much as possible. But I probably went a bit too far ;-).