【问题标题】:SQL - Does Not Include The Specified Expression as an Aggregate FunctionSQL - 不包含指定表达式作为聚合函数
【发布时间】:2013-03-04 19:37:28
【问题描述】:

我正在尝试编写一个查询来计算和列出学生的 GPA,然后只显示低于所有学生平均 GPA 的那些。我已成功获得查询以输出每个学生的 GPA 表,但我无法让它仅显示低于平均水平的表。

以下是我当前的查询:

    SELECT SC.StudentID, S.StdLastName, GPA
    FROM (SELECT SC.StudentID, S.StdLastName, ROUND(SUM(C.Credits * GV.GradeValue)/SUM(C.Credits), 2) AS GPA
         FROM ((Student_Classes AS SC INNER JOIN GradeValues AS GV ON SC.Grade = GV.Grade) 
         INNER JOIN Students AS S ON SC.StudentID = S.StudentID)
         INNER JOIN Classes as C ON SC.ClassID = C.ClassID
         GROUP BY SC.StudentID, S.StdLastName)
    GROUP BY SC.StudentID, S.StdLastName, GPA
    HAVING GPA < AVG(GPA)
    ORDER BY GPA;

当我这样做时,出现的错误是,

您尝试执行的查询不包含指定表达式 GPA

我在此站点上发现了多个页面上的类似错误,但仍然无法使其正常工作。任何帮助将不胜感激。

【问题讨论】:

  • 您能确认您使用的是什么数据库吗?这似乎不是 MySQL 语法,主要是由于缺少派生表别名和额外的括号。它看起来像 MS Access。
  • @bluefeet 是的,对不起。把mySQL放错了。这是在 MS Access 中。
  • 感谢您的确认,我想确保您找到正确的人来查看问题。 :)
  • 这个查询存在一个基本问题:group by GPA 将导致AVG(GPA) 始终等于GPA。我怀疑该错误是因为您尝试在其中一个分组列上使用聚合函数。
  • @Allan 我不确定我是否理解。如果我没有在 GROUP BY 中包含 GPA,我会收到一个错误,因为 SELECT 中不是函数的任何内容都需要在 GROUP BY 中,不是吗?

标签: sql ms-access


【解决方案1】:

当您说 GROUP BY SC.StudentID, S.StdLastName, GPA 时,您是在告诉数据库使用这三列来创建数据组,然后在每个组中应用聚合函数(在本例中为 AVG)。这意味着,正如所写,您正在尝试根据该学生的平均水平过滤每个学生的 GPA。希望每个学生的平均 GPA 等于他们的实际 GPA...

为了完成这项工作,您需要第二个子查询,您可以使用它来获取总体平均 GPA:

SELECT sc.studentid, s.stdlastname, gpa
FROM   (SELECT sc.studentid, 
               s.stdlastname, 
               ROUND(SUM(c.credits * gv.gradevalue) / SUM(c.credits), 2) AS gpa
        FROM      ((student_classes sc
              INNER JOIN gradevalues gv
                 ON sc.grade = gv.grade)
              INNER JOIN students s
                 ON sc.studentid = s.studentid)
        GROUP BY sc.studentid, s.stdlastname)
GROUP BY sc.studentid, s.stdlastname, gpa
WHERE gpa < (SELECT AVG(GPA) as avg_gpa 
               FROM (SELECT ROUND(SUM(c.credits * gv.gradevalue) / SUM(c.credits), 2) AS gpa
                     FROM  student_classes sc
                           INNER JOIN gradevalues gv
                                   ON sc.grade = gv.grade
                     GROUP BY sc.studentid))
ORDER BY gpa;

我不确定这是否会解决您的语法问题,但它应该可以解决您的逻辑问题。

【讨论】:

  • 嗯。是的,那里有一些问题,但我明白了要点。我会尝试一下。谢谢。
  • 太棒了。通过一些小的编辑,这很有效。非常感谢艾伦。
【解决方案2】:

这是否消除了错误?如果是这样,您可以从这里选择 sid、lname 和 GPA

  SELECT SC.StudentID, S.StdLastName, GPA, avg(GPA) as avgGPA
FROM (SELECT SC.StudentID, S.StdLastName, ROUND(SUM(C.Credits * GV.GradeValue)/SUM(C.Credits), 2) AS GPA
     FROM ((Student_Classes AS SC INNER JOIN GradeValues AS GV ON SC.Grade = GV.Grade) 
     INNER JOIN Students AS S ON SC.StudentID = S.StudentID)
     INNER JOIN Classes as C ON SC.ClassID = C.ClassID
     GROUP BY SC.StudentID, S.StdLastName)
WHERE GPA < avg(GPA)
GROUP BY SC.StudentID, S.StdLastName, GPA
    ORDER BY GPA;

【讨论】:

  • 我之前尝试过。说在 WHERE 子句中不能有聚合函数。因此我尝试了 HAVING。
  • 无论如何,我很欣赏苏格兰威士忌的时光。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多