SQL的老题目:查询学生平均成绩及其名次
2009-02-16 17:39
1066 查看
SQL的老题目了。
Student(S#,Sname,Sage,Ssex) 学生表
Course(C#,Cname,T#) 课程表
SC(S#,C#,score) 成绩表
Teacher(T#,Tname) 教师表
24、查询学生平均成绩及其名次
答:SELECT 1+(SELECT COUNT( distinct 平均成绩)
FROM (SELECT S#,AVG(score) AS 平均成绩
FROM SC
GROUP BY S#
) AS T1
WHERE 平均成绩 > T2.平均成绩) as 名次,
S# as 学生学号,平均成绩
FROM (SELECT S#,AVG(score) 平均成绩
FROM SC
GROUP BY S#
) AS T2
ORDER BY 平均成绩 desc;
网上找了一下,没有分析的文章,或许太简单了。那我们自己来分析。这里涉及到一个SELECT 表1.* FROM 表1 where 表1.字段=表2.字段的表遍历匹配的问题(表1、表2是数据库中同一个表或同一个表查询结果的别名)。
但是代码一大堆,看得一头雾水,我们先拆开来,看T1表的查询(先去了COUNT有助于我们的分析)。
图 T1
接着看,T2表的查询。(加入"order by 平均成绩",可以让之后的对比效果更明显)
图 T2
对比T1和T2的SQL查询语句及结果,可以看出,除了distinct的效果以外,其他代码基本上一致。
拆分开来看,是简单的SQL语句,那么联合起来是一种什么效果呢?语句执行的顺序又是什么呢?
我们参照图T1和图T2一步步来描述语句的执行顺序。
清晰理解了这一点,相信整段SQL代码就不难理解了。完整查询结果如下:
另外需要补充一点的是distinct在这里的使用效果。
需不需要distinct,要看排名的要求方式,要distinct是指顺序排名(如上面的例子,则为1,2,2,3...),不要是指跳序排名(如上面的例子,则为1,2,2,4...)。可见后者其实就是我们日常成绩的排名方式。
Student(S#,Sname,Sage,Ssex) 学生表
Course(C#,Cname,T#) 课程表
SC(S#,C#,score) 成绩表
Teacher(T#,Tname) 教师表
24、查询学生平均成绩及其名次
答:SELECT 1+(SELECT COUNT( distinct 平均成绩)
FROM (SELECT S#,AVG(score) AS 平均成绩
FROM SC
GROUP BY S#
) AS T1
WHERE 平均成绩 > T2.平均成绩) as 名次,
S# as 学生学号,平均成绩
FROM (SELECT S#,AVG(score) 平均成绩
FROM SC
GROUP BY S#
) AS T2
ORDER BY 平均成绩 desc;
网上找了一下,没有分析的文章,或许太简单了。那我们自己来分析。这里涉及到一个SELECT 表1.* FROM 表1 where 表1.字段=表2.字段的表遍历匹配的问题(表1、表2是数据库中同一个表或同一个表查询结果的别名)。
但是代码一大堆,看得一头雾水,我们先拆开来,看T1表的查询(先去了COUNT有助于我们的分析)。
SELECT distinct 平均成绩 FROM (SELECT S#,AVG(score) AS 平均成绩 FROM SC GROUP BY S#) T1
图 T1
接着看,T2表的查询。(加入"order by 平均成绩",可以让之后的对比效果更明显)
SELECT S#,AVG(score) 平均成绩 FROM SC GROUP BY S# order by 平均成绩
图 T2
对比T1和T2的SQL查询语句及结果,可以看出,除了distinct的效果以外,其他代码基本上一致。
拆分开来看,是简单的SQL语句,那么联合起来是一种什么效果呢?语句执行的顺序又是什么呢?
我们参照图T1和图T2一步步来描述语句的执行顺序。
循环第一次 for (select @i=1 from T2 order by 平均成绩 desc) { //取出 T2.平均成绩 = 87 if(T1.平均成绩 > T2.平均成绩) //即扫一遍T1看下有没有大于87的 { return count(T1.平均成绩); //返回0个(T1中没有大于87的) } } 循环第二次 for (select @i=2 from T2 order by 平均成绩 desc) { //取出 T2.平均成绩 = 85 if(T1.平均成绩 > T2.平均成绩) //即扫一遍T1看下有没有大于85的 { return count(T1.平均成绩); //返回1个(T1中刚好有87,大于T2的85) } } 循环第三次 for (select @i=3 from T2 order by 平均成绩 desc) { //取出 T2.平均成绩 = 85 if(T1.平均成绩 > T2.平均成绩) //即扫一遍T1看下有没有大于85的 { return count(T1.平均成绩); //返回1个(T1中刚好有87,大于T2的85) } } 循环第四次 for (select @i=4 from T2 order by 平均成绩 desc) { //取出 T2.平均成绩 = 83 if(T1.平均成绩 > T2.平均成绩) //即扫一遍T1看下有没有大于85的 { return count(T1.平均成绩); //返回2个(T1中刚好有87,85,大于T2的83) } } 以此类推... 直到遍历匹配完毕。
清晰理解了这一点,相信整段SQL代码就不难理解了。完整查询结果如下:
另外需要补充一点的是distinct在这里的使用效果。
需不需要distinct,要看排名的要求方式,要distinct是指顺序排名(如上面的例子,则为1,2,2,3...),不要是指跳序排名(如上面的例子,则为1,2,2,4...)。可见后者其实就是我们日常成绩的排名方式。
相关文章推荐
- 查询学生平均成绩及其名次
- 查询学生平均成绩及其名次_24
- Oracle SQL题目及其解答(学生、课程、成绩、教师)
- Oracle SQL题目及其解答(学生、课程、成绩、教师)
- SQL查询每门科目的成绩大于80的学生名字
- 查询学生 学号、姓名和平均成绩
- [关于SQL]查询成绩都大于80分的学生
- SQL语句多表查询(学生表/课程表/教师表/成绩表 ){转载}
- sql查询每门课程成绩最高的学生
- sql语句多表查询(学生表/课程表/教师表/成绩表 )
- 查询出“张”姓学生中平均成绩大于75分的学生信息
- Sql -- 练习1 查询每科成绩前两名的学生信息
- 一个SQL查询出每门课程的成绩都大于80的学生姓名
- 转 一个题目涉及到的50个Sql语句(学生成绩)
- 五十道编程小题目 --- 50 有五个学生,每个学生有3门课的成绩,计算出平均成绩,况原有的数据和计算出的平均分数存放在磁盘文件"stud"中java
- 一道简单的SQL面试题:查询成绩排名第10到第20的学生
- 查询来自不通地点的学生平均成绩,只显示平均成绩大于等于80的地区
- 【程序50】TestStu.java 题目:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩), //计算 出平均成绩,况原有的数据和计算出的平均分数存放在磁盘
- MySQL实现ROW_NUMBER()---(给查询平均成绩的结果加上名次)
- SQL查询每所学校语文成绩最高的学生信息