Oracle中真正稳妥的求三甲的方法

旧巷老猫 提交于 2021-01-09 05:17:35

坐地铁回家路上忽然想起,三甲排名可能为多个,只取三名岂不荒谬。不信请看下面数据:

create table tb_score(
    id number(4,0) primary key,
    name nvarchar2(20) not null,
    score integer not null)

insert into tb_score values('1','Andy','100');
insert into tb_score values('2','Bill','99');
insert into tb_score values('3','Cindy','100');
insert into tb_score values('4','Douglas','99');
insert into tb_score values('5','Eliot','98');
insert into tb_score values('6','Flex','98');
insert into tb_score values('7','Hellen','98');
insert into tb_score values('8','jack','97');
insert into tb_score values('9','king','95');
insert into tb_score values('10','tim','92');
insert into tb_score values('11','yang','91');

明显100分的状元有Andy,Cindy两人,99分的榜眼也有两人,98分的探花有三人。

正确的做法是按分数分组,名字累加,再取分数最高的三个等级,SQL如下:

select b.* from
(
    select a.*,rownum as rn  from
    (
        select listagg(name,',') within group (order by name) as names from tb_score
        group by score
        order by score  desc
    ) a
) b
where b.rn<4

数据如下:

SQL> select b.* from
  2  (
  3  select a.*,rownum as rn  from
  4  (
  5  select listagg(name,',') within group (order by name) as names from tb_score
  6  group by score
  7  order by score  desc
  8  ) a
  9  ) b
 10  where b.rn<4;

NAMES                                    RN
-------------------------------- ----------
 A n d y, C i n d y                       1
 B i l l, D o u g l a s                   2
 E l i o t, F l e x, H e l l e n          3

这才是公平公正和稳妥的排名。

--2020年4月23日--

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!