订阅更新

每场考试都处于中游的学生

SQL 实战 123 题 · 第 106 题 困难 约 2 分钟读完

LeetCode 1412 · 排除极值、双向排名、反连接

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

先用 RANK() OVER (PARTITION BY exam_id ORDER BY score DESC) 和升序的 RANK 找出所有在某场考试里拿过最高或最低分的学生,再从考试表里的学生中排除他们,关联姓名并排序。「每一场都满足」很难正面写,转成「任何一场都不违反」用排除法更简单。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

学生表和考试成绩表。「中游」指在某场考试里既不是最高分也不是最低分。找出参加过考试、并且在参加的每一场考试里都处于中游的学生,按学生 ID 排序。

表结构

  • Student:student_id(主键)、student_name
  • Exam:exam_id、student_id、score;(exam_id, student_id) 为主键

思路

反过来想:只要在任何一场考试里拿过最高分或最低分,就不合格。先按考试分区做升序和降序两个排名,找出所有拿过第一或最后的学生;再从参加过考试的学生里排除他们。以考试表为起点自然排除了没参加过考试的学生。

参考解法

select e.student_id,student_name
from Exam e left join Student s
on e.student_id=s.student_id
where e.student_id not in(
    select student_id
    from(
        select student_id,rank() over(partition by exam_id order by score desc) rkmax, rank() over(partition by exam_id order by score ) rkmin
        from Exam 
    )t1
    where rkmax = 1 or rkmin =1
)
group by e.student_id,student_name
order by e.student_id

易错点

  • 从学生表出发 NOT IN,没参加过考试的学生也会被选出来,题目要求排除。
  • 一场考试里并列最高或并列最低的都算极值,用 RANK。
刷题进度保存在当前浏览器