R10-8 查询选修了2门以上课程的学生学号和平均成绩。 分数 10 较难 作者 白彦辉 单位 赤峰学院 题干: 查询选修了2门以上课程的学生学号和平均成绩。 提示:请使用SELECT语句作答。 表结构: 定义表结构的SQL语句如下: CREATE TABLE student ( sno varchar(6) NOT NULL , sname varchar(10) , sex char(2) , nation char(2) , pnum char(18) , birth date , phone char(11) , dept varchar(20) , PRIMARY KEY (sno) ) ; CREATE TABLE course ( cno varchar(6) NOT NULL, cname varchar(20) , credit int(11) , attribute varchar(10) , PRIMARY KEY (cno) ) ; CREATE TABLE score ( sno varchar(6) NOT NULL, cno varchar(6) NOT NULL, term varchar(15), grade int(11), PRIMARY KEY (sno,cno) ) ;
时间: 2025-06-26 14:01:22 浏览: 18
<think>好的,我现在要解决用户的问题:如何用SELECT语句查询选修了多于两门课程的学生学号及其平均成绩,涉及student、course和score三张表。首先,我需要理解数据库的结构。根据引用[2],数据库中有学生表(Student)、课程表(Course)、成绩表(Score)和教师信息表(Teacher)。题目中只涉及前三个表,但实际成绩可能只与Score表相关,因为成绩通常记录在Score表中,而Course表可能包含课程信息,但选课数量可能由Score表中的记录决定。
接下来,我需要确定每个表的结构。假设学生表Student有学号(S#)、姓名(Sname)等字段;课程表Course有课程号(C#)、课程名等;成绩表Score可能有学号(S#)、课程号(C#)、成绩(Score)等。根据引用[1],多表查询的例子中使用了t_student和t_student_course(可能对应Score表),通过学号连接。因此,要统计每个学生选修的课程数,应该从Score表中按学号分组,然后计算每组的课程数,筛选出超过两门的记录。
所以,基本步骤是:首先从Score表中按S#分组,使用COUNT(C#)统计课程数,然后用HAVING COUNT(C#) > 2过滤,同时用AVG(Score)计算平均成绩。但需要注意是否需要排除同一课程多次选修的情况,比如同一课程重修,但题目中可能默认每门课程只选一次,或者按记录数计算。如果允许同一课程多次选修,是否需要算作多门?这里可能用户需求是统计不同课程的数量,但题目没有说明,所以假设每个C#代表不同课程,直接计数即可。
是否需要连接Student表?题目要求输出学号和平均成绩,这些信息在Score表中都有,所以可能不需要连接其他表。但用户提到涉及三个表,可能需要确认是否Score表中有成绩,而课程信息在Course表中。但实际情况中,成绩直接关联学号和课程号,因此可能不需要连接Course表,除非需要验证课程是否存在。但题目可能只是需要统计Score表中的记录,所以可能只需Score表即可。
可能的错误点:是否需要处理NULL值?比如,如果有学生的成绩为NULL,是否影响计数?根据题意,可能只要选修了课程(有Score记录)就算,不管成绩是否为NULL。因此COUNT(C#)或COUNT(*)都可以,但COUNT(C#)会忽略C#为NULL的情况,而COUNT(*)不会。但通常C#是外键,不会为NULL,所以两种方法都可以。
综上,正确的SQL语句应该是:
SELECT S#, AVG(Score) AS 平均成绩
FROM Score
GROUP BY S#
HAVING COUNT(C#) > 2;
但用户提到涉及三个表,可能需要检查是否需要JOIN操作。例如,如果课程信息需要来自Course表,或者学生姓名来自Student表,但题目只需要学号和平均成绩,所以可能不需要连接。但用户可能误以为需要三个表,这时候需要进一步分析。比如,是否存在Score表中没有课程号,需要通过Course表来关联?但根据引用[1],Score表包含C#字段,所以不需要。因此,可能用户的问题中涉及的三个表是多余的,只需Score表即可。
不过,可能用户提供的表结构中,成绩表Score中的课程号需要与Course表关联,但统计选修课程数量时,并不需要Course表的信息,所以不需要连接。因此,最终的SQL只需要在Score表上操作。
另外,是否需要考虑学生是否存在于Student表中?比如,是否有Score表中的学号在Student表中不存在的情况。但根据题目要求,可能不需要考虑这种情况,只需按Score表中的数据统计即可。
最后,测试示例:假设Score表中有学生A选了3门课程,成绩分别为80、85、90,那么他的平均成绩是85,应该被查询出来。而学生B选了2门课程,则不会被包含。</think>要查询选修超过两门课程的学生学号及平均成绩,可通过以下步骤实现:
### SQL查询语句
```sql
SELECT s.S#, AVG(sc.Score) AS 平均成绩
FROM Score sc
JOIN Student s ON sc.S# = s.S#
GROUP BY s.S#
HAVING COUNT(DISTINCT sc.C#) > 2
```
### 分步解释
1. **数据来源定位**
成绩记录存储在`Score`表中,包含学号(`S#`)、课程号(`C#`)和成绩(`Score`)。学生信息在`Student`表中,但查询仅需学号,因此通过`JOIN`确保学号有效性[^2]。
2. **聚合计算逻辑**
- `GROUP BY s.S#`:按学号分组统计
- `COUNT(DISTINCT sc.C#)`:计算每个学生选修的不同课程数量,避免重复课程干扰
- `HAVING COUNT(...) > 2`:筛选选修超过两门课程的学生[^1]
3. **性能优化考量**
`DISTINCT`关键字确保同一课程多次选修仅计为1次。若需包含重复选修的课程,可改为`COUNT(sc.C#)`。
### 示例数据验证
假设`Score`表部分数据如下:
| S# | C# | Score |
|-----|-----|-------|
| S01 | C01 | 80 |
| S01 | C02 | 85 |
| S01 | C03 | 90 |
| S02 | C01 | 75 |
则查询结果仅返回学号`S01`,其平均成绩为$ \frac{80+85+90}{3} = 85 $。
阅读全文
相关推荐


















