我有一个我正在尝试优化的SQL查询。
有没有更好的方法可以避免在这里使用子查询? 得到了关于使用Row_number()的建议, 发布此内容并进行一些更正
DECLARE @curdate DATETIME
SET @curdate = GETDATE()
SELECT DISTINCT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
Assessment ASMT ON SIS.StudentID = ASMT.StudentId
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
AND StudentCoverageData.StudentCoverageDataID = (SELECT TOP 1 StudentCoverageData.StudentCoverageDataID
FROM StudentCoverage
INNER JOIN StudentCoverageData ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverage.StudentId = SIS.StudentID
AND StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= @curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > @curdate)
ORDER BY StudentCoverageData.AsOfDate DESC)
答案 0 :(得分:1)
子查询中的所有表都存在于内连接子句中,因此您可以像这样重写查询:
;WITH temps AS
(
DECLARE @curdate DATETIME = GETDATE()
SELECT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate,
ROW_NUMBER() OVER (PARTITION BY StudentCoverageData.StudentCoverageDataID ORDER BY StudentCoverageData.AsOfDate) AS RowIndex
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= @curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > @curdate)
)
SELECT * FROM temps t
WHERE t.RowIndex = 1