2017-04-02 117 views
0

我有一個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) 

回答

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 
+0

我需要選擇TOP 1 StudentCoverageData.StudentCoverageDataID – user2212827

+0

我剛剛編輯....如果您需要TOP1 Of All,請在我的查詢 – TriV

+0

中刪除「PARTITION BY StudentCoverageData.StudentCoverageDataID」,看起來相當不錯,謝謝。 – user2212827