mysql - 使用嵌套子查询和 GROUP BY 的 SQL 查询

标签 mysql sql subquery

我编写了一个查询,可以根据多个表中的信息计算学生的 GPA:

SELECT Major DNO, DName Dept, FName, LName,
    (SUM(g.gradepoint*c.Credits)/SUM(c.Credits)) GPA
FROM Student s, Enrolled_in e, Gradeconversion g, Course c, Department d
WHERE s.StuID=e.StuID and e.Grade=g.lettergrade and e.CID=c.CID and d.DNO=s.Major
GROUP BY e.StuID;

产生以下输出:

+------+-----------------------+---------+----------+------------------+
| DNO  | Dept                  | FName   | LName    | GPA              |
+------+-----------------------+---------+----------+------------------+
|  600 | Computer Science      | Linda   | Smith    |  3.3187500089407 |
|  600 | Computer Science      | Tracy   | Kim      | 3.08235291873708 |
|  600 | Computer Science      | Shiela  | Jones    | 3.05999999046326 |
|  600 | Computer Science      | Dinesh  | Kumar    | 2.78947370930722 |
|  600 | Computer Science      | Paul    | Gompers  | 2.89999998699535 |
|  600 | Computer Science      | Andy    | Schultz  | 2.98823530533734 |
|  600 | Computer Science      | Lisa    | Apap     | 3.32105263910796 |
|  600 | Computer Science      | Jandy   | Nelson   |              3.2 |
|  600 | Computer Science      | Eric    | Tai      | 3.01923077840071 |
|  600 | Computer Science      | Derek   | Lee      | 3.61304346374843 |
|  600 | Computer Science      | David   | Adams    |              3.3 |
|  600 | Computer Science      | Steven  | Davis    | 3.18750002980232 |
|  600 | Computer Science      | Charles | Norris   | 3.57142857142857 |
|  600 | Computer Science      | Susan   | Lee      |  3.5071428673608 |
|  600 | Computer Science      | Mark    | Schwartz |  2.9434782733088 |
|  600 | Computer Science      | Bruce   | Wilson   | 3.05789474437111 |
|  600 | Computer Science      | Michael | Leighton | 3.17058825492859 |
|  600 | Computer Science      | Arthur  | Pang     | 2.89999998699535 |
|  520 | ECE                   | Ian     | Thornton |                4 |
|  520 | ECE                   | George  | Andreou  | 2.94782609524934 |
|  540 | Chemical Engineering  | Michael | Woods    | 3.26666665960241 |
|  520 | ECE                   | David   | Shieber  |            3.375 |
|  540 | Chemical Engineering  | Stacy   | Prater   | 3.06666667373092 |
|  520 | ECE                   | Mark    | Goldman  | 3.42307692307692 |
|  520 | ECE                   | Eric    | Pang     |  3.7562500089407 |
|  520 | ECE                   | Paul    | Brody    | 2.90526317295275 |
|  550 | Mathematical Sciences | Eric    | Rugh     | 3.82499998807907 |
|  100 | History               | Jun     | Han      | 3.10500003099442 |
|  550 | Mathematical Sciences | Lisa    | Cheng    | 2.95384616118211 |
|  550 | Mathematical Sciences | Sarah   | Smith    | 3.09230767763578 |
|  550 | Mathematical Sciences | Eric    | Brown    | 2.98000001907349 |
|  550 | Mathematical Sciences | William | Simms    |              3.8 |
|   50 | Cognitive Science     | Eric    | Epp      | 3.11249998211861 |
|   50 | Cognitive Science     | Sarah   | Schmidt  | 3.08125002682209 |
+------+-----------------------+---------+----------+------------------+

现在我需要找到这个表中对应于每个专业 GPA 最低的学生的元组 我的想法是做这样的事情:

SELECT DNO, Dept, FName, LName, MIN(GPA) GPA FROM
    (SELECT Major DNO, DName Dept, FName, 
        LName,(SUM(g.gradepoint*c.Credits)/SUM(c.Credits)) GPA
    FROM Student s, Enrolled_in e, Gradeconversion g, Course c, Department d
    WHERE s.StuID=e.StuID and e.Grade=g.lettergrade and e.CID=c.CID and d.DNO=s.Major
    GROUP BY e.StuID) p
GROUP BY Dept;

但这会产生:

+------+-----------------------+---------+----------+------------------+
| DNO  | Dept                  | FName   | LName    | GPA              |
+------+-----------------------+---------+----------+------------------+
|  540 | Chemical Engineering  | Michael | Woods    | 3.06666667373092 |
|   50 | Cognitive Science     | Eric    | Epp      | 3.08125002682209 |
|  600 | Computer Science      | Linda   | Smith    | 2.78947370930722 |
|  520 | ECE                   | Ian     | Thornton | 2.90526317295275 |
|  100 | History               | Jun     | Han      | 3.10500003099442 |
|  550 | Mathematical Sciences | Eric    | Rugh     | 2.95384616118211 |
+------+-----------------------+---------+----------+------------------+

找到了每个系的最低 GPA,但它与该系中恰好排在第一位的学生 fname 和 lname 相关,而不是与实际 GPA 最低的 fname 和 lname 相关。我知道当您使用 GROUP BY 时,SELECT 中不属于聚合函数的每个属性都应该出现在 GROUP BY 中。我只是不确定如何继续此查询来获取我正在寻找的值。任何帮助将不胜感激,因为我对此很陌生!

最佳答案

您需要另一层嵌套和另一层 JOIN 来实现这一点。使用 VIEW 将为您提供可重用性和轻松的查询构建。

因此,第一步,将原始查询存储在如下 View 中:

CREATE VIEW GPAS AS
SELECT Major DNO, DName Dept, FName, LName,
    (SUM(g.gradepoint*c.Credits)/SUM(c.Credits)) GPA
FROM 
  Student s, Enrolled_in e, Gradeconversion g, Course c, Department d
WHERE s.StuID=e.StuID and e.Grade=g.lettergrade 
and e.CID=c.CID and d.DNO=s.Major
GROUP BY e.StuID;

现在,重现您提到的第一个结果就像这样做一样简单

select * from gpas

现在说重点:显然,您的第二个查询将被重写为

SELECT DNO, Dept, FName, LName, MIN(GPA) GPA 
FROM GPAS p ORDER BY Dept.

但它仍然会返回相同的结果,对吧?要实现您想要的目标,请执行以下操作:

select * from gpas g
join (select dept,MIN(GPA) mingpa from gpas group by dept) mingpas mg
on (g.dept=mg.dept and g.GPA=mg.mingpa)

您可以看到使用 View 使这变得多么容易和更加全面。但是,如果您决定不使用它们,请将上述查询中的每个 FROM GPAS 替换为

FROM (YourOriginalQuery) AS somealias

关于mysql - 使用嵌套子查询和 GROUP BY 的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19347205/

相关文章:

php - 需要通过 css 将颜色添加到 html 表格

php - 如何按时间范围从观看开始时间和观看持续时间获取观众?

mysql - SQL - 检查是否存在重叠的工作时间

c# - 基于关联属性聚合的约束查询

json - Postgresql jsonb_agg 子查询排序

php - 错误代码 : 1093. 您无法在 FROM 子句中指定用于更新的目标表 'mm'

Mysql获取条件中描述的所有记录,即使它不存在于表中

mysql - 在一张表中添加第二个外键 - MySql

sql - 如果确切时间不可用,如何根据最后一个可用时间戳返回值?

mysql - 获取子查询 where 子句 id 与主查询中的 id 匹配