关于mysql进行学生成绩名次和及格率的计算mysql
1 Student(S_,Sname,Sage,Ssex) 学生表 2 S_:学生编号,字符串型 3 Sname: 学生姓名,字符串型 4 Sage:年龄 ,数值型 5 Ssex:性别,字符串型 6 7 Course(C_,Cname,T_) 课程表 8 C_:课程编号 ,字符串型 (企业管理001,马列002,UML 003,数据库004,英语006) 9 Cname:课程名称 ,字符串型 10 T_:教师编号,字符串型 11 12 SC(S_,C_,score) 成绩表 13 S_:学生编号 ,字符串型 14 C_:课程编号 ,字符串型 15 score:成绩,数值型 16 17 Teacher(T_,Tname) 教师表 18 T_:教师编号 ,字符串型 19 Tname:教师姓名,字符串型
1 SELECT 2 1+ ( 3 SELECT 4 COUNT( DISTINCT 平均成绩 ) 5 FROM 6 ( SELECT S_, AVG( score ) AS 平均成绩 FROM SC GROUP BY S_ ) AS T1 7 WHERE 8 平均成绩 > T2.平均成绩 9 ) AS 名次, 10 S_ AS 学生学号, 11 平均成绩 12 FROM 13 ( SELECT S_, AVG( score ) 平均成绩 FROM SC GROUP BY S_ ) AS T2 14 ORDER BY 15 平均成绩 DESC;
1 +------+----------+-----------+ 2 | 名次 | 学生学号 | 平均成绩 | 3 +------+----------+-----------+ 4 | 1 | 1005 | 99.000000 | 5 | 2 | 1010 | 85.500000 | 6 | 3 | 1003 | 84.250000 | 7 | 4 | 1004 | 75.000000 | 8 | 5 | 1007 | 71.333333 | 9 | 6 | 1006 | 68.250000 | 10 | 7 | 1012 | 66.000000 | 11 | 8 | 1011 | 57.750000 | 12 | 9 | 1001 | 56.000000 | 13 | 10 | 1002 | 47.500000 | 14 | 11 | 1008 | 44.000000 | 15 | 12 | 1009 | 34.000000 | 16 +------+----------+-----------+ 17 12 rows in set (0.06 sec)
上述的查询语句中运用了不少技巧,可是咱们只挑几个重点进行讲解,至于相关自查询就没有讲解,以及distinct也没有讲解,distinct的讲解这里推荐一篇博文。面试
A n+的使用算法
n+放在()子查询的前面,这里的n是代表指定的字段的数值是从n开始的,若是是1就是从1开始,2就是从2开始。而后+的意思就是该字段的值从n开始每次都+1,这里和Java自增++的使用有些神似,固然这是这两个彻底没有关系。这里是1+那么就是从1开始每一个值加1,方向取决于如何排序和用什么字段进行排序。sql
B 排序算法的讲解数据库
简单解释下这个查询运用到的排序算法,首先按照学生进行分组,以后运用了相关子查询同时使用了distinct关键字去除了彻底相同的列。将平均成绩和相同表格的平均成绩进行一一比较,对于当前平均成绩比其余平均成绩高的行记录进行了计数。以表1为例,就是学号1001的平均成绩和1002-1012进行了比较,若是该成绩大于其余平均成绩就+1。这时每位同窗都比较完了,那么获得了一个以学生编号为分组的并且记录了平均成绩高于其余同窗的平均成绩的次数表2。此时的表2的开始值是0,所以此时1+就派上了用场,用初始值变成了1,那么接下来对其进行排序就能够获得名次表,就如以上的结果演示表。函数
注:表格分解学习
表1:平均成绩表spa
1 +------+-----------+ 2 | S_ | 平均成绩 | 3 +------+-----------+ 4 | 1001 | 56.000000 | 5 | 1002 | 47.500000 | 6 | 1003 | 84.250000 | 7 | 1004 | 75.000000 | 8 | 1005 | 99.000000 | 9 | 1006 | 68.250000 | 10 | 1007 | 71.333333 | 11 | 1008 | 44.000000 | 12 | 1009 | 34.000000 | 13 | 1010 | 85.500000 | 14 | 1011 | 57.750000 | 15 | 1012 | 66.000000 | 16 +------+-----------+
表2:高于其余成绩次数表.net
1 +------+------+ 2 | 学号 | 次数 | 3 +------+------+ 4 | 1001 | 8 | 5 | 1002 | 9 | 6 | 1003 | 2 | 7 | 1004 | 3 | 8 | 1005 | 0 | 9 | 1006 | 5 | 10 | 1007 | 4 | 11 | 1008 | 10 | 12 | 1009 | 11 | 13 | 1010 | 1 | 14 | 1011 | 7 | 15 | 1012 | 6 | 16 +------+------+
1 SELECT 2 t.C_ AS 课程号, 3 max( course.Cname ) AS 课程名, 4 ifnull( AVG( score ), 0 ) AS 平均成绩, 5 100 * SUM( CASE WHEN ifnull( score, 0 ) >= 60 THEN 1 ELSE 0 END ) / COUNT( * ) AS 及格百分数 6 FROM 7 SC T, 8 Course 9 WHERE 10 t.C_ = course.C_ 11 GROUP BY 12 t.C_ 13 ORDER BY 14 ifnull(avg(score),0),100 * SUM( CASE WHEN ifnull( score, 0 ) >= 60 THEN 1 ELSE 0 END ) / COUNT( * ) DESC;
1 +--------+----------+-----------+------------+ 2 | 课程号 | 课程名 | 平均成绩 | 及格百分数 | 3 +--------+----------+-----------+------------+ 4 | 004 | 数据库 | 48.200000 | 40.0000 | 5 | 001 | 企业管理 | 59.142857 | 57.1429 | 6 | 002 | 马列 | 65.400000 | 60.0000 | 7 | 006 | 英语 | 67.750000 | 75.0000 | 8 | 003 | UML | 84.750000 | 100.0000 | 9 +--------+----------+-----------+------------+
其实这段代码也没有什么能够解释的,就是一些函数的和选择结构的运用code
A ifnull()函数的使用
这里的ifnull的做用是为了保证成绩不为空,其实就是将为空的成绩变成0,方便计算。ifnull函数的用法是ifnull(字段,值(若是前面的字段值是null就返回此值)),推荐一个博客讲述该函数用法。其实ifnull也能够用coalesce()函数进行替代,他们的用法是彻底同样的,或者使用if(表达式1,值1,值2)。
B case嵌套在汇集函数sum()
这里确实是一个新的知识点,通常咱们不多在汇集函数中去嵌套选择结构或者语法,这里却用到了这样的方法让人耳目一新。这里的case语句的做用是使得大于60的成绩为1和小于60为0,为了方便sum函数统计及格人数。值得注意的一点是这里case的用法和平时的语法不同,通常在非自定义函数或者存储过程当中的case用法是(case 字段 when 条件 then 值 else 值 end 字段)。可是这里直接就case 而后中间同样以后就end了。这一点是很是须要注意的,固然在存储过程当中又不同,存储过程当中的case是以end case结尾的。