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有助于我们的分析)。

view plaincopy to clipboardprint?
SELECT distinct 平均成绩 FROM (SELECT S#,AVG(score) AS 平均成绩   
FROM SC GROUP BY S#) T1 
SELECT distinct 平均成绩 FROM (SELECT S#,AVG(score) AS 平均成绩
FROM SC GROUP BY S#) T1

图 T1

接着看,T2表的查询。(加入"order by 平均成绩",可以让之后的对比效果更明显)

view plaincopy to clipboardprint?
SELECT S#,AVG(score) 平均成绩 FROM SC GROUP BY S# order by 平均成绩 
SELECT S#,AVG(score) 平均成绩 FROM SC GROUP BY S# order by 平均成绩

图 T2

对比T1和T2的SQL查询语句及结果,可以看出,除了distinct的效果以外,其他代码基本上一致。

拆分开来看,是简单的SQL语句,那么联合起来是一种什么效果呢?语句执行的顺序又是什么呢?

我们参照图T1和图T2一步步来描述语句的执行顺序。
view plaincopy to clipboardprint?
循环第一次  
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)  
    }  
}  
 
以此类推... 直到遍历匹配完毕。 
循环第一次
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...)。可见后者其实就是我们日常成绩的排名方式。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/djlzxzy/archive/2009/02/16/3897069.aspx

SQL的老题目:查询学生平均成绩及其名次相关推荐

  1. mysql查询学生平均成绩及其名次_数据库面试题:数据库查询语句

    Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题 ...

  2. mysql查询学生平均成绩及其名次_sql 统计 学生成绩2

    文章来源:http://www.ynpxrz.com/n822738c2024.aspx t_tudent(sid,sname,sage,ssex,sdept) 学生表 t_course(cid,cn ...

  3. -- 24、查询学生平均成绩及其名次

    SELECT st.s_id,st.s_name,ROUND((CASE WHEN AVG(sc.s_score) IS NULL THEN 0 ELSE AVG(sc.s_score) END),2 ...

  4. 浙大版《C语言程序设计(第3版)》题目集 练习3-3 统计学生平均成绩与及格人数 (15 分)...

    练习3-3 统计学生平均成绩与及格人数 (15 分) 本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数.题目保证输入与输出均在整型范围内. 输入格式: 输入在第一行中给出非 ...

  5. 某班有5名同学,建立一个学生的简单信息表,包括学号、姓名、3门课程的成绩,编写程序,计算每名学生的平均成绩及名次。(30分) 题目内容: 某班有5名同学,建立一个学生的简单信息表,包括学号、姓名、3

    某班有5名同学,建立一个学生的简单信息表,包括学号.姓名.3门课程的成绩,编写程序,计算每名学生的平均成绩及名次.(30分) 题目内容: 某班有5名同学,建立一个学生的简单信息表,包括学号.姓名.3门 ...

  6. 统计学生平均成绩与及格人数(PTA)

    7-3 统计学生平均成绩与及格人数 (15 分) 本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数.题目保证输入与输出均在整型范围内. 输入格式: 输入在第一行中给出非负整 ...

  7. 三个学生四门课程,求出学生平均成绩和课程的平均成绩;n个学生每人m门课程,找出最高分学生,输出有一门成绩不合格的学生的各门成绩,计算每门成绩都在85分及以上的学生的人数(C)

    养成好习惯,点个赞 再走:有问题,欢迎私信.评论,我看到都会回复的 以下两个题目就是玩一下for循环语句和二维数组 文章目录 三个学生四门课程,求出学生平均成绩和课程的平均成绩 n个学生,每人m门课程 ...

  8. MySql 学生表 科目表 成绩表 查询学生各科成绩

    MySql 学生表 科目表 成绩表 查询学生各科成绩 2016年08月16日 01:05:02 lzxomg 阅读数 8155 版权声明:本文注明出处可以转载. https://blog.csdn.n ...

  9. C语言简单算法之求交错序列前N项和,统计学生平均成绩与及格人数,求1到100的和,求奇数分之一序列前N项和,找出最小值,求n!,统计字符,最佳情侣身高差

    C语言简单算法之求交错序列前N项和,统计学生平均成绩与及格人数,求1到100的和,求奇数分之一序列前N项和,找出最小值,求n!,统计字符,最佳情侣身高差 [1] 1.题目三 求交错序列前N项和 1.实 ...

最新文章

  1. 细数技术指标-[转载]
  2. SAP PM入门系列22 - IH06 Display Functional Location
  3. Spring Boot 如何快速改造老项目?
  4. Nginx域名访问与访问控制
  5. linux编码 form表单,Linux curl 模拟form表单提交信息和文件
  6. Java银行开户,取钱,存钱,查询余额,退出。。。。。
  7. 使用一个程序同时启动多个程序(c#)
  8. ios下点击label包含的input checkbox或radio无效问题
  9. Q139:PBRT-V3,Metropolis Light Transport (MLT)(16.4章节)
  10. UILabel 实现圆角
  11. 人工智能在安全漏洞方面的应用_智慧消防平台的智慧在哪方面?
  12. 如何查看 MySQL 数据库的引擎
  13. HTML代码页面无法跳转为什么,html跳转新页面代码_html页面跳转代码
  14. Linux命令大全(最详细)Linux操作系统上课笔记整理
  15. excepted one 0f #, =>at line16,column 16(byte 311)
  16. 关于ppp、PPPoE、PPTP、L2TP、IPSec协议的简单认识
  17. js: color-thief在浏览器中拾取图片的主色调
  18. 女巫小屋的指令Java_我的世界女巫小屋详介绍 我的世界女巫小屋种子代码一览...
  19. 如何开发一个植物识别,人工智能植物识别系统毕业设计毕设作品
  20. spark进行数据清洗时,如何读取xlsx表格类型文件

热门文章

  1. 信息学奥赛一本通 1084:幂的末尾 | OpenJudge NOI 小学奥数 7833
  2. 信息学奥赛一本通(1321:【例6.3】删数问题(Noip1994))
  3. 图论 —— 图的连通性 —— 传递闭包
  4. 统计难题(HDU-1251)
  5. 14 MM配置-BP业务伙伴-定义供应商科目组和字段选择
  6. 11 所允许的仓储单位类型没有针对仓储类型xxx定义
  7. php mongodb 视频教程,燕十八mongodb视频资料分享
  8. Windows编译环境搭建(VS2010)
  9. 2021.08.22学习内容torch.cat()和torch.stack()函数
  10. Scala里Map()集合