您的位置:首页 > 职场人生

【MYSQL学习】面试题:查询每个班的第二名(考虑并列)的信息

2019-03-20 22:22 225 查看

查询每个班的第二名(考虑并列)

数据源

create table s1 (
id int,
name varchar(10),
score int,
classno int)

insert into s1 values
(1,xxj,100,1),
(2,xxj2,100,1),
(3,xxj3,99,1,),
(4,xxj4,99,1),
(5,xf,99,2),
(6,xf2,98,2),
(7,xf3,98,2),
(8,xz,100,3),
(9,xz2,98,3)

方法一:使用dense_rank() over() 函数

四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)
这里主要用到dense_rank(),dense_rank函数出现相同排名时,不跳过相同排名号,rank值紧接上一次的rank值。这正是我们所需要的。

语法

select DENSE_RANK() OVER
(partition by [classno] order by [score]) as den_rank,* from [s1]

具体SQL

select * from (select dense_rank()
over (partition by classno order by score desc) as
rankk,s1.name,s1.score,s1.classno,s1.id from s1 ) as s2
where rankk = 2;

方法二:子查询

刚看到这道题不知道有这个函数,只想着用子查询解决该问题,想法是首先查询出每个班的第一名的分数max(score),再查询除去刚刚查询出的第一名分数的max(score)也就是第二名,找到所需信息即可。

为了避免特殊情况,再构建数据源时考虑了三种情况,一个班两个并列第一,一个班两个并列第二,一个班一个第一一个第二,同时分数存在一个班的第二名可能是另一个班的第一名。尽量把所有情况都考虑到。

代码如下:

select max(score) as second,classno from s1
where score not in
( SELECT max(score) FROM s1 group by classno) group by classno;

结果选不出1班的第二名,因为1班的第二名是二班的第一名,所以这种方法考虑不全面,不正确。

如果有不用函数来解决这个问题的方法,欢迎指导~~很想知道有没有构建子查询的方法!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: