2013-04-09 93 views
0

我的設立是這樣的:我有三個表 -SQL的子查詢與聚合函數(SQL Server)的

  • 學生(StudentID,名字,姓氏等)
  • StudentSemesters(StudentID,semid的等等),以及
  • 學期(semid的,年)

我的要求是,讓每一個學生,但只爲自己的最後一個學期的細節。從邏輯上講,這意味着該年度數字最高的學期。我似乎無法獲得查詢權。爲了簡單起見,「年」只是一個整數(例如2000年,1998年)。下面是我一直停留在一段時間當前查詢:

SELECT dbo.Student.LastName + ' , ' + dbo.Student.FirstName AS Student, dbo.Student.Defence1Date, dbo.Student.Defence2Date, COUNT(StudentSemesters_1.SemID) 
      AS SemesterCount, dbo.Student.EntrySemester + ' - ' + 
       (SELECT dbo.StudentSemesters.SemID 
       FROM dbo.StudentSemesters INNER JOIN 
           dbo.ListSemesters ON dbo.StudentSemesters.SemID = dbo.ListSemesters.SemID 
       WHERE (dbo.Student.StudentCode = dbo.StudentSemesters.StudentCode) 
       GROUP BY dbo.StudentSemesters.SemID, dbo.ListSemesters.Year 
       HAVING (dbo.ListSemesters.Year = MAX(dbo.ListSemesters.Year))) AS Expr1 
FROM dbo.Student INNER JOIN 
      dbo.StudentSemesters AS StudentSemesters_1 ON dbo.Student.StudentCode = StudentSemesters_1.StudentCode 
GROUP BY dbo.Student.LastName, dbo.Student.FirstName, dbo.Student.Defence1Date, dbo.Student.Defence2Date, dbo.Student.EntrySemester, 
      dbo.Student.StudentCode 

回答

0

你可以做到這一點,以獲得詳細信息只爲每個學生最後一個學期:

SELECT 
    s.LastName + ' , ' + s.FirstName AS Student, 
    s.Defence1Date, 
    s.EntrySemester + ' - ' + s1.SemId AS Expr1 
FROM dbo.Student    AS s 
INNER JOIN dbo.StudentSemesters AS S1 ON s.StudentCode = S1.StudentCode 
INNER JOIN dbo.ListSemesters AS lm ON lm.SemID  = s1.SemId 
INNER JOIN 
(
    SELECT SemId, MAX(Year) AS MaxYear 
    FROM dbo.StudentSemesters 
    GROUP BY SemId 
) AS s2 ON s2.semId = lm.SemId AND ls.Year = s2.MaxYear; 

然而,如果你使用SQL Server 2005 +,你可以使用窗口函數來進行:

WITH CTE 
AS 
(
    SELECT 
     s.LastName + ' , ' + s.FirstName AS Student, 
     s.Defence1Date, 
     s.EntrySemester + ' - ' + s1.SemId AS Expr1, 
     ROW_NUMBER() OVER(PARTITION BY s1.SemId 
         ORDER BY Year DESC) AS RowNumber 
    FROM dbo.Student    AS s 
    INNER JOIN dbo.StudentSemesters AS S1 ON s.StudentCode = S1.StudentCode 
    INNER JOIN dbo.ListSemesters AS lm ON lm.SemID  = s1.SemId 
) 
SELECT 
    Student, 
    Defence1Date, 
    Expr1, 
FROM CTE 
WHERE RN = 1; 

但這不會得到SemesterCount,但你可能會這樣做(這只是一個猜測):

SELECT 
    s.LastName + ' , ' + s.FirstName AS Student, 
    s.Defence1Date, 
    s1.SemCount, 
    s.EntrySemester + ' - ' + s1.SemId AS Expr1 
FROM dbo.Student    AS s 
INNER JOIN 
(
    SELECT StudentCode, COUNT(SemId) AS SemCount 
    FROM dbo.StudentSemesters 
    GROUP BY StudentCode 
) AS S1 ON s.StudentCode = S1.StudentCode 
INNER JOIN dbo.ListSemesters AS lm ON lm.SemID  = s1.SemId 
INNER JOIN 
(
    SELECT SemId, MAX(Year) AS MaxYear 
    FROM dbo.StudentSemesters 
    GROUP BY SemId 
) AS s2 ON s2.semId = lm.SemId AND ls.Year = s2.MaxYear;