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. markdown使用总结

    # markdown简介> Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面. —— [维基百科]( https://zh.w ...

  3. loj 1271

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26981 思路:题目的意思是求给定的起点到终点的最短路径序列,并且这 ...

  4. iOS 钥匙串 指纹识别 get和Post请求的区别

    01-钥匙串 1. 通过系统提供的钥匙串功能可以在本地保存密码,系统使用AES的方式对密码加密 a. 查看Safari中保存的密码 2. 使用第三方框架SSKeychain把密码保存到钥匙串和获取钥匙 ...

  5. 构造函数创建对象和Object.create()实现继承

    第一个方法用构造函数创建对象,实现方法的继承 /*创建一个对象把所有公用的属性和方法,放进去*/ function Person() { this.name = "W3cplus" ...

  6. 分布式文件系统FastDFS设计原理(转)

    FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker server).存储服务器(storage server)和客户端(client)三个部分组成,主要解决了海量数据存储问题 ...

  7. hibernate快速入门

    第一步:下载Hibernate的开发包: http://sourceforge.net/projects/hibernate/files/hibernate3 第二步:Hibernate框架目录结构: ...

  8. 【转】Struts2国际化

    原文章:http://www.cnblogs.com/hellokitty1/p/5083663.html 简单理解     国际化简称i18n,其来源是英文单词 internationalizati ...

  9. mybatis 加载配置文件的两种方式

    package com.atguigu.day03_mybaits.test; import java.io.IOException;import java.io.InputStream;import ...

  10. Codeforces Round #375 (Div. 2) - C

    题目链接:http://codeforces.com/contest/723/problem/C 题意:给定长度为n的一个序列.还有一个m.现在可以改变序列的一些数.使得序列里面数字[1,m]出现次数 ...