15.7 Imagine a simple database storing information for students' grades. Design what this database might look like and provide a SQL query to return a list of the honor roll students (top 10%), sorted by their grade point average.

在一个简化的数据库中我们有三个表,Students表,Courses表和CourseEnrollment表如下:

TABLE Students

+-------------+-------------+
| Students |
+-------------+-------------+
| StudentID | int(11) |
| StudentName | varchar(30) |
| Address | varchar(50) |
+-------------+-------------+

TABLE Courses

+-------------+-------------+
| Courses |
+-------------+-------------+
| CourseID | int(11) |
| CourseName | varchar(30) |
| ProfessorID | int(11) |
+-------------+-------------+

TABLE CourseEnrollment

+-----------+---------+
| CourseEnrollment |
+-----------+---------+
| CourseID | int(11) |
| StudentID | int(11) |
| Grade | float |
| Term | int(11) |
+-----------+---------+

使用SQL Server的Top .. Percent 函数可以如下代码:

-- SQL Server (Incorrect Code)
SELECT TOP 10 PERCENT AVG(CourseEnrollment.Grade) AS GPA, CourseEnrollment.StudentID
FROM CourseEnrollment GROUP BY CourseEnrollment.StudentID ORDER BY AVG(CourseEnrollment.Grade);

由于我使用的是MySQL,本来可以用Limit关键字来做,但是MySQL的Limit关键字后面只能为常量,不能为变量,所以只能换一种写法,所以代码如下:

SET @limit = (SELECT 0.1 * COUNT(*) FROM CourseEnrollment);
SELECT Grade FROM (
SELECT *, @rownum := @rownum + 1 AS rank
FROM CourseEnrollment, (SELECT @rownum := 0) init ORDER BY Grade DESC
) d WHERE rank <= @limit ;

但是上面的写法确实返回了top 10%的行,但是假如我们有100个学生,前15个学生都是4.0的GPA,而上面的方法只能返回10个学生,而我们需要返回那15个都是4.0的学生,所以为了实现这个,我们可以这么做:

-- SQL Server
DECLARE @GPACutOff FLOAT;
SET @GPACutOff = (SELECT MIN(GPA) AS 'GPAMin' FROM (
SELECT TOP 10 PERCENT AVG(CourseEnrollment.Grade) AS GPA, FROM CourseEnrollment
GROUP BY CourseEnrollment.StudentID ORDER BY GPA DESC) Grades); SELECT StudentName, GPA FROM (
SELECT AVG(CourseEnrollment.Grade) AS GPA, CourseEnrollment.StudentID
FROM CourseEnrollment GROUP BY CourseEnrollment.StudentID
HAVING AVG(CourseEnrollment.Grade) >= @GPACutOff) Honors
INNER JOIN Students ON Honors.StudentID = Students.StudentID;

上面的方法先定义了一个GPACutOff变量,算出了前10%的GPA,然后在后面的代码中遍历所有的GPA,返回所有大于等于GPACutOff的行。而是用MySQL可以写出实现同样功能的代码,参考了我之前的博客Department Top Three SalariesDepartment Highest SalarySecond Highest Salary,用更简洁的方式如下:

-- MySQL
SELECT c.Grade FROM CourseEnrollment c WHERE (SELECT COUNT(DISTINCT Grade) FROM CourseEnrollment
WHERE Grade > c.Grade) < (SELECT 0.1 * COUNT(*) FROM CourseEnrollment) ORDER BY c.Grade DESC;

要注意那些潜在的假设,比如看上面的设计,一个潜在的假设就是每门课只能由一个教授交,而在一些学校,课程可能被多个教授交。但是,我们需要做一些假设,而潜在的一些不正确的假设需要多加注意。

我们需要在灵活性和复杂性之间做出平衡,比如设计一个课程可以被多个教授交的系统是增加了灵活性,但是也增加了复杂度,如果我们的系统对于任何情况都适用,那么系统就会无比的复杂。所以我们需要设计出一个相对灵活的系统,但仍然有假设和限定,这不仅需要数据库设计的知识,还包括了面向对象的设计。

CareerCup All in One 题目汇总

[CareerCup] 15.7 Student Grade 学生成绩的更多相关文章

  1. 学生成绩管理系统(C++指针、链表、文件及面向对象的运用)

    学生成绩管理系统 功能页面显示:    实现源码: #include<iostream> #include<fstream> #include<cstring> # ...

  2. C语言项目:学生成绩管理系统

    C语言项目:学生成绩管理系统    1.数据结构:学生信息:学号.姓名.年龄.性别.3课成绩    2.功能:   (1)增加学生记录    (2)  删除学生记录    (3)  查找学生信息(学号 ...

  3. JAVA基础代码分享--学生成绩管理

    问题描述: 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10  等级为’A’   成绩>=最高分-20  等级为’B’ 成绩>=最高分-30  等级为’C’ ...

  4. sql面试题一 学生成绩

    sql面试题一 学生成绩   原帖链接:http://topic.csdn.net/u/20081020/15/1ABF54D0-F401-42AB-A75E-DF90027CEBA0.html 表架 ...

  5. c++学生成绩管理系统

    虽然比较水 =.= 但是写了两节课+一个中午 都是强迫症的锅 http://www.cnblogs.com/wenruo/p/4940182.html #include <cstdio> ...

  6. C语言练手自己编写学生成绩管理系统

    #include<stdio.h> #include<stdlib.h> /*定义学生结构体*/ struct Student { ]; ]; float Mark1; flo ...

  7. 【学生成绩管理系统】 大二c语言作业

    几年前写的了,只能在命令行窗口运行,虽然比较挫,还是有一定参考价值... #include <cstdio> #include <conio.h> #include <i ...

  8. 学生成绩管理C++版

    [标题]学生成绩管理的设计与实现 [开发语言]C++ [主要技术]STL [概要设计]类名:student 类成员:No.Name.Math.Eng.Chn.Cpro.Sum 成员函数:getname ...

  9. JAVA课程设计个人博客 学生成绩管理 201521123001 张陈东芳

    1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 我主要负责实现学生信息的添加功能.学生成绩的录入 ...

随机推荐

  1. jsp,图片显示

    问题:jsp中显示项目中image文件夹中的图片 1,项目中image文件夹中有对应的图片 2,<img ,src="/项目名/image/图片名.jpg">,用其他变 ...

  2. 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)

    函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...

  3. HDU 5787 K-wolf Number 数位DP

    K-wolf Number Problem Description   Alice thinks an integer x is a K-wolf number, if every K adjacen ...

  4. Java学习笔记(十)——多态

    一.多态 1.对象的多种形态 (1)引用多态: 父类的引用可以指向本类的对象 父类的引用可以指向子类的对象 (2)方法多态: 创建本类对象时,调用的方法为本类方法: 创建子类对象时,调用的方法是子类方 ...

  5. WPD:Page Download Time Breakdown选项详解

    WPD:Page Download Time Breakdown选项详解 “页面下载时间细分”图显示每个页面组件下载时间的细分,可以根据它确定在网页下载期间事务响应时间缓慢是由网络错误引起还是由服务器 ...

  6. 开发Portlet第三步:如何在Crystal Portlet中调用远程服务?

    当基于测试数据的Portlet调试完成后,接下来就是引入远程服务,替换测试数据. (此处以Dubbo框架远程服务为例) 分步指南 删除测试数据依赖:在pom.xml文件中,删除对****-servic ...

  7. JQuery学习之操作DOM

    1.DOM,就是Document Object Model(文档对象模型) 2.获得内容的方法: **text():设置或返回所选元素的文本内容 $("#btn1").click( ...

  8. 分享Kali Linux 2016.2第46周虚拟机

    分享Kali Linux 2016.2第46周虚拟机该虚拟机使用Kali Linux 2016.2第46周的64位镜像安装.桌面为Gnome模式.该虚拟机配置如下:(1)支持VMWare 9以上的版本 ...

  9. BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树

    [题目分析] 主席树,维护区间大小以及权值之和. 但是细节确实要琢磨很久,WA了几次. [代码] #include <cstdio> #include <cstring> #i ...

  10. hdu 1078 FatMouse and Cheese

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...