每个班级前5%的学生名单前5%学生成绩,计算5%时若非整数向上取整怎么写?

sql
student表 字段: stu_id 学生id 、stu_name 学生姓名、grade 成绩
calss表、字段: cla_id 班级id、cla_name 班级名称、stu_id 学生id
**结果表字段:班级名称,每个班级前5%的学生名单,前5%学生成绩
其中,每个班级学生成绩无重复人数大于5,计算5%时若非整数向上取整。

分析:

  1. 题目中没说前5%的排序依据,不清楚是指总分占比还是指分数排名的前5%,这里假设是按分数倒序排名,排名占人数的占比为前5%,
    即如果班级是20人,那么就只要找出1人,而低于20人时,向上取整皆为只取一人
  2. 题目中没有指定数据库及版本,不同数据库的语法是有区别的,但由于目前大部分数据库均已支持开窗函数,因此结合第一点,给出下面的sql
    select x.cla_name,x.stu_name,x.grade from (
    select c.cla_name,s.stu_name,s.grade,
    ROW_NUMBER() OVER(PARTITION BY c.cla_id order by s.grade desc) rn,
    count(1) OVER(PARTITION BY c.cla_id ) ct
    from student s,class c where s.stu_id=c.stu_id
    ) x where (
    (ct > 20 and rn/ct<=0.05 ) or
    (ct <= 20 and rn=1)
    )
    

如果是指每班输出人数大于5的话,用下面这个

select x.cla_name,x.stu_name,x.grade from (
select c.cla_name,s.stu_name,s.grade,
dense_rank() OVER(PARTITION BY c.cla_id order by s.grade desc) rk,
count(1) OVER(PARTITION BY c.cla_id ) ct
from student s,class c where s.stu_id=c.stu_id
) x where (
(rk<=6 or cell(rk/ct*100)<=5 ) 

能不能把你的create table 和数据的insert发出一下?
题目要求是无重复且大于5人,dense_rank排行就是重复分排行一样,且排名递增为1。
然后排行为前5%,你题目中并没有说这个5%是要怎么计算得到的,光排序排名至少就有3种方式取前5%,分数占比排名也至少有2种方式取前5%,因此在题目不明确的情况下,选择和前面一致的dense_rank,下面的sql稍微改了一下分母的取值

select x.cla_name,x.stu_name,x.grade from (
select c.cla_name,s.stu_name,s.grade,
dense_rank() OVER(PARTITION BY c.cla_id order by s.grade desc) rk,
count(distinct x.grade) OVER(PARTITION BY c.cla_id ) ct
from student s,class c where s.stu_id=c.stu_id
) x where (
(rk<=6 or cell(rk/ct*100)<=5 )

cell向上取整

floor向下取整
用上面的cell函数就可以

在不明确班级有多少人的情况下,
指定要取每个班级前5%的学生名单,
顺便带着成绩每个班级学生成绩无重复且 人数大于5