I have a StudentScores table as below in SQL Server 2012 . The classification system is weighted using special rules. There will be one row for each student MATHS result in the result set. The row may or may not have an estimate for the SCIENCE and LITERATURE columns based on the availability of available scores "within two months from the date of the MATHS result for SCIENCE" and "within one month from the date of the MATHS result for LITERATURE".
Note. This is the script that I created to simplify my business domain problem.
I created the following query with subqueries. Is there a way to rewrite it without subqueries and more efficiently?
TABLE
DECLARE @StudentScores TABLE (StudentMarkID INT IDENTITY(1,1) NOT NULL, StudentID INT, SubjectCode VARCHAR(10), ResultDate DATETIME, Score DECIMAL(5,2)) INSERT INTO @StudentScores (StudentID,SubjectCode,ResultDate,Score) SELECT 1, 'MATHS','2016-01-10',35 UNION ALL SELECT 1, 'LITERATURE','2016-01-10',62 UNION ALL SELECT 1, 'SCIENCE','2016-01-30',65 UNION ALL SELECT 1, 'SCIENCE','2016-02-02',61 UNION ALL SELECT 1, 'LITERATURE','2016-02-03',60 UNION ALL SELECT 1, 'MATHS','2016-03-25',55 UNION ALL SELECT 2, 'LITERATURE','2016-01-10',12 UNION ALL SELECT 2, 'SCIENCE','2016-01-30',14 UNION ALL SELECT 2, 'SCIENCE','2016-02-14',12 UNION ALL SELECT 2, 'LITERATURE','2016-02-14',15 UNION ALL SELECT 2, 'MATHS','2016-03-25',18
QUERY
SELECT SS.StudentID, Score AS MathsScore, ResultDate AS MathsResultDate, (SELECT TOP 1 Score FROM @StudentScores S2 WHERE S2.StudentID = SS.StudentID AND S2.SubjectCode = 'SCIENCE' AND S2.ResultDate >= DATEADD(MONTH,-2,SS.ResultDate) ORDER BY s2.ResultDate DESC ) AS ScienceScore, (SELECT TOP 1 ResultDate FROM @StudentScores S2 WHERE S2.StudentID = SS.StudentID AND S2.SubjectCode = 'SCIENCE' AND S2.ResultDate >= DATEADD(MONTH,-2,SS.ResultDate) ORDER BY s2.ResultDate DESC ) AS ScienceResultDate, (SELECT TOP 1 Score FROM @StudentScores S2 WHERE S2.StudentID = SS.StudentID AND S2.SubjectCode = 'LITERATURE' AND S2.ResultDate >= DATEADD(MONTH,-1,SS.ResultDate) ORDER BY s2.ResultDate DESC ) AS LiteratureScore, (SELECT TOP 1 ResultDate FROM @StudentScores S2 WHERE S2.StudentID = SS.StudentID AND S2.SubjectCode = 'LITERATURE' AND S2.ResultDate >= DATEADD(MONTH,-1,SS.ResultDate) ORDER BY s2.ResultDate DESC ) AS LiteratureResultDate FROM @StudentScores SS WHERE SS.SubjectCode = 'MATHS'
Expected Result
