首先这是Score表(如果有选课表和课程表 也可以关联成一张表)
这是User表
我一开始遇到这个问题不会,在网上看到这篇文章http://www.jb51.net/article/50160.htm
上面写了一个参考的程序是
SELECT A.ID,U.Name,A.ScoreName,A.Score
FROM Score A,[User]U
WHERE UID IN (SELECT TOP 1 UID
FROM Score B
WHERE B.ScoreName = A.ScoreName
ORDER BY B.Score DESC) AND A.UID=U.UID
ORDER BY A.ScoreName, A.Score DESC
基本意思是先通过Score表自连接 ,按照分数排序,查询出每个单科第一(TOP 1表示返回第一项)的学生学号(UID),然后根据括号里传回来的三个单科第一的学生学号,查出对应的学生姓名和科目名以及分数。
运行结果是这样
我看不太懂为什么可以这样,于是想测试一下
但是当我打开我的mysql实测的时候,发现运行不了,因为他的TOP 1 ,mysql并不支持,而mysql支持的limit却不能嵌套进子查询里面,会报错
那我用mysql要怎么改呢,我想起之前我用limit查询出的数据类似这样
select * from (select * from A limit 5) AS foo where ….
就是将limit查询到的数据当成一个表 给这个表取个别名叫 foo 。
就把UID换到from里面去,而且既然是表,就没必要只查一个UID了,改成了
SELECT UID, max(Score)
FROM score
WHERE score.ScoreName = score.ScoreName
GROUP BY Score DESC LIMIT 3
把它插入到之前那个里面取个别名叫 B,为了防止跟原本的Score弄混淆,
给max(Score)取别名叫maxScore,于是得到
SELECT ID ,`Name` ,ScoreName,maxScore
FROM score A , `user` U , (
SELECT UID ,MAX(Score) AS ‘maxScore’
FROM score
WHERE score.ScoreName = score.ScoreName
GROUP BY Score DESC limit 3) AS B
WHERE A.UID = U.UID AND A.Score = B.maxScore
GROUP BY A.ScoreName
测试依然报错,于是我先把子查询测试出来,然后再在外查询后面加limit ,
最终测试成功的代码为:
SELECT ID ,`Name` ,ScoreName,maxScore
FROM score A , `user` U , (
SELECT UID ,MAX(Score) AS ‘maxScore’
FROM score
WHERE score.ScoreName = score.ScoreName
GROUP BY Score DESC) AS B
WHERE A.UID = U.UID AND A.Score = B.maxScore
GROUP BY A.ScoreName LIMIT 3
测试结果为:
再看成绩表和学生表,单科最高的确实分别是李四 数学88,张三英语 99和赵六语文 98.
但是我的代码仍然有不完善的地方,比如这个表比较短,所以我知道只有语文数学英语三科,limit 3
如果是整个大学所有系的所有专业,科目根本数不过来,怎么获取limit的值具体是多少呢。请大家帮忙完善吧。
参考文档:http://www.jb51.net/article/50160.htm