最近看见一道数据库的面试题,面试的是测试,感觉查询很复杂,特意建个表试了一下。一共三个表,班级、学生、成绩,如下:

每个班级分数最高的学生 mysql 按班级汇总最高分_MySQL

每个班级分数最高的学生 mysql 按班级汇总最高分_联合查询_02

每个班级分数最高的学生 mysql 按班级汇总最高分_联合查询_03

题目是:查询每班分数最高的学生。

先看一下所有人分数总和,这个比较简单,只要联合查询就可以了(我直接用了别人写的一个语句,没有inner join这种关键字,也是能查出来的):

每个班级分数最高的学生 mysql 按班级汇总最高分_MySQL_04

这题的思路如果是:根据班级分组,求出总分,再取出每班的最高分和姓名,那结果与预期就很诡异了。

每个班级分数最高的学生 mysql 按班级汇总最高分_联合查询_05

里面的查询直接用了上面查总分的语句,外面又写一个取姓名和每个班的最高分的语句,仔细看最高分查出来了,但是和上面的查询结果对比一下就发现,姓名和分数没对上。不过再思考一下也就差不多了,这步只取出每个班的最高分,再与上面的查询结果再联合查询一次,下面就是我对这题写出的一个庞大的语句:

每个班级分数最高的学生 mysql 按班级汇总最高分_MySQL_06

这大段特意加了缩进,好看一些。上面是查询所有学生的班级、姓名和总分,下面是查询出每个班最高分,两个临时表联合查询,查出我理解的题意。因为我用的是MySQL,这里还有一个坑,就是我圈出来的那a,aaa,b,这种子查询的表是需要别名的,如果是Oracle好像没有这个限制。

其实这题还有第二问:查询每班不及格科目数大于2的学生。大于2的恐怕没有,最多大于等于2,只有一个。

每个班级分数最高的学生 mysql 按班级汇总最高分_每个班级分数最高的学生 mysql_07

有人说我第二个语句错了,确实是错了,哈哈。下面放上正确的语句,加个分组,如果两个人满足条件,不加分组只会查出一个人,把小天的分数也改成两门不及格。

select t3.ClassName,StuName from student t1
     inner join score t2 on t1.StuId=t2.StuId
     inner join class t3 on t1.ClassId=t3.ClassId
     where Score<60 group by t2.StuId HAVING count(*)>=2;

每个班级分数最高的学生 mysql 按班级汇总最高分_子查询_08

感觉第二问并不是很难,虽然having count这种用的比较少(至少我测试时候没用过),第一问简直不能再绕,不知道出题人是不是真正知道正确答案;还是出题人只是理论上知道答案,如果只是理论上知道答案,恐怕只能查出最早的那个错的结果。对于这种面试失败的只能说命不好了。