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