【问题标题】:SQL- Subquery with aggregate functions (SQL Server)SQL- 带有聚合函数的子查询 (SQL Server)
【发布时间】:2013-04-09 09:18:02
【问题描述】:

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

  • 学生(学生 ID、名字、姓氏等),
  • 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

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    您可以这样做以仅获取每个学生最后一个学期的详细信息:

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      相关资源
      最近更新 更多