Postgresql(版本10)中,遵循sql,按avg_grade选择所有行。

-- query - students list, order by average grade,
select s.student_id, s.student_name, avg(ce.grade) as avg_grade
from students as s
       left join course_enrollment as ce on s.student_id = ce.student_id
group by s.student_id
order by avg_grade desc NULLS LAST;

相关表格
学生:
create table students (
  student_id   bigserial                           not null primary key,
  student_name varchar(200)                        not null,
  created      timestamp default CURRENT_TIMESTAMP not null
);

课程注册:
-- create table,
create table course_enrollment
(
  course_id  bigint                              not null,
  student_id bigint                              not null,
  grade      float                               not null,
  created    timestamp default CURRENT_TIMESTAMP not null,
  unique (course_id, student_id)
);

问题:
如何仅检索值最大的前n%(例如10%)行?
想知道是否有一个窗口函数来执行此操作,或者需要一个子查询?
顺便说一句:
这与Postgresql : How do I select top n percent(%) entries from each group/category
因为它需要每个组的前n%,所以它可以使用avg_grade中的分区。
但这一个需要前n%的总体,因此window functions是必需的。

最佳答案

我将使用子查询:

select student_id, student_name, avg_grade, rank() over (order by avg_grade desc)
from (select s.student_id,
             s.student_name,
             avg(ce.grade)                                        as avg_grade,
             rank() over (order by avg(ce.grade) desc nulls last) as seqnum,
             count(*) over ()                                     as cnt
      from students s
             left join
           course_enrollment ce
           on s.student_id = ce.student_id
      group by s.student_id
     ) as ce_avg
where seqnum <= cnt * 0.1;

您还可以使用其他窗口功能,例如NTILE()PERCENTILE_DISC()。我更喜欢直接计算,因为它能更好地控制领带的处理方式。

关于sql - 在Postgresql中,如何按列选择前n%的行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54957288/

10-11 11:54