题解 | #考试分数(三)#
考试分数(三)
https://www.nowcoder.com/practice/b83f8b0e7e934d95a56c24f047260d91
v1 想直接group by + order by + limit,结果做不出来
v2 用窗口函数
主要逻辑:
- 用窗口函数 给每个language_id 组内 按score倒序后,标记序号rank_number
- 筛选每个组里 rank_number =1和2,即第1名和第2名 (因为用的是dense_rank,因此如果有同值的情况也能查出来)
select
a.id,
a.name,
a.score
from (
select
g.id,
l.name,
g.score,
dense_rank()over(partition by g.language_id order by g.score desc) as rank_number
from grade g
left join language l on g.language_id=l.id
)a
where a.rank_number in (1,2)
order by
a.name asc,
a.score desc,
a.id asc
v3 参考评论答案,尝试不用窗口函数,直接用select join解决
主要逻辑:先找出「分数比当前分数高」的记录个数,当记录个数少于2个的时候,说明这条记录是最高值或第二高的值
select
a.id,
l.name,
a.score
from
(
select
g1.language_id,
g1.id,
g1.score
from grade g1, grade g2
# 这里不能用join,会导致多一行c++ 11000的数据。至于为啥,目前没头绪
where g2.score >= g1.score and
g1.language_id = g2.language_id
group by g1.language_id,g1.id
having count(distinct g2.score)<=2
)a
left join language l on a.language_id=l.id
order by
l.name asc,
a.score desc,
a.id asc
在子查询中,from 一行,我刚开始用了join:from grade g1 join grade g2 on g1.id=g2.id
结果一直多一行c++ 11000的数据。
最后改为 from grade g1, grade g2才行。至于为啥,目前没头绪,希望有知道的大佬能帮忙看看
