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

时间:2013-10-13 16:01:35

标签: 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中。我只是不确定如何继续这个查询来获取我正在寻找的值。任何帮助都会非常感激,因为我对此很新!

1 个答案:

答案 0 :(得分:2)

你需要另一个级别的嵌套和另一个JOIN来完成它。使用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)

您可以看到使用视图更容易和更全面。但是,如果您决定不使用它们,请使用

替换上述查询中的每个FROM GPAS
FROM (YourOriginalQuery) AS somealias