在MySQL中操纵两个子查询的结果

时间:2012-02-15 20:23:19

标签: mysql subquery correlated-subquery

对于家庭作业,我必须编写一个MySQL查询来计算数据库表中每个学生的GPA。我将问题分解为3个部分:(1)计算每个学生获得的成绩点数,(2)计算学分数,然后(3)将学分分为学分。以下是我为第1步和第2步编写的查询:

  1. 计算获得的成绩点数:

    SELECT ID, SUM( credits ) AS credits_taken
    FROM takes
    NATURAL JOIN course 
    GROUP BY ID
    
  2. 2查找获得的成绩积分:

        SELECT ID, SUM( credits * ( SELECT points FROM gradepoint WHERE letter = grade ) ) AS tot_grade_points
        FROM takes NATURAL JOIN course
        GROUP BY ID 
    

    我手动评估每个查询并返回正确的结果。但我无法弄清楚如何为每个学生返回(credits_taken / tot_grade_points)。这是我尝试过的:

        SELECT ID, GPA
        FROM student AS S NATURAL JOIN
                (SELECT ID,( 'credits_taken' / SUM( credits * ( SELECT points FROM gradepoint WHERE letter = grade ) )) AS GPA
                 FROM takes AS T1 NATURAL JOIN course
                 WHERE S.ID = T1.ID
                 AND EXISTS (
                               SELECT ID, SUM( credits ) AS 'credits_taken'
                               FROM takes AS T2 NATURAL JOIN course
                               WHERE S.ID = T2.ID
                               GROUP BY ID
                              ) 
                 GROUP BY ID) Z
        GROUP BY ID
    

    但是这给了我''子句'中的错误“未知列'S.ID'”。根据我的阅读,您无法在连接操作中从子查询引用表的别名。有没有人有另一种方法来计算这两个子查询并将它们绑定到学生ID?

    'take'表将学生ID映射到他们所学课程的信息,最重要的是course_id和成绩。 “课程”表包含“学分”字段,该课程的学分数。

    修改

    以下是相关的表格结构:

    需要:

        Field     | Type         | Null | Key | Default | Extra |
       +-----------+--------------+------+-----+---------+-------+
       | ID        | varchar(5)   | NO   | PRI |         |       |
       | course_id | varchar(8)   | NO   | PRI |         |       |
       | sec_id    | varchar(8)   | NO   | PRI |         |       |
       | semester  | varchar(6)   | NO   | PRI |         |       |
       | year      | decimal(4,0) | NO   | PRI | 0       |       |
       | grade     | varchar(2)   | YES  |     | NULL    |       |
       +-----------+--------------+------+-----+---------+-------+
    

    当然:

       +-----------+--------------+------+-----+---------+-------+
       | Field     | Type         | Null | Key | Default | Extra |
       +-----------+--------------+------+-----+---------+-------+
       | course_id | varchar(8)   | NO   | PRI |         |       |
       | title     | varchar(50)  | YES  |     | NULL    |       |
       | dept_name | varchar(20)  | YES  | MUL | NULL    |       |
       | credits   | decimal(2,0) | YES  |     | NULL    |       |
       +-----------+--------------+------+-----+---------+-------+
    

1 个答案:

答案 0 :(得分:1)

我会尝试:

SELECT takes.sec_id, 
  SUM( course.credits * gradepoint.points ) / SUM( course.credits ) AS GPA
FROM takes
JOIN gradepoint ON takes.grade = gradepoint.letter
JOIN course ON takes.course_id = course.course_id
GROUP BY takes.sec_id

由于您的表结构描述不完整,我不得不猜测gradepoint架构,我假设sec_id标识takes表中的学生,如果有另一列,则只需在SELECT的查询中替换它}和GROUP BY部分。也许它是ID,但像这样的列名通常用于主键。或者根本没有定义主键,这无论如何都是不好的做法。如果你想要除id以外的任何学生信息,你也需要加入student表。

我还建议使用JOIN ... ON ...语法而不是NATURAL JOIN,它不仅更具可读性,还为您提供更多灵活性,例如,查看如何加入gradepoint而不是使用代价高昂的从属子查询。