带有聚合函数的SQL-子查询(SQL Server)

时间:2013-04-09 00:58:15

标签: sql-server

我的设置是这样的:我有三张桌子 -

  • 学生(StudentID,FirstName,LastName等),
  • StudentSemesters(StudentID,SemID等)和
  • 学期(SemID,年)

我的要求是,获取每个学生的详细信息,但仅限于他们的最后一个学期。从逻辑上讲,这意味着具有最高年份数的学期。我似乎无法正确查询。为简单起见,'Year'只是一个整数(例如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

1 个答案:

答案 0 :(得分: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;