题解 | 找出每个学校GPA最低的同学

找出每个学校GPA最低的同学

https://www.nowcoder.com/practice/90778f5ab7d64d35a40dc1095ff79065

思路分析:

本题的题意明确,就是找出每个学校gpa最小的同学,输出他的device_id,university,gpa。第一眼想到GROUP BY university,然后MIN(gpa),但是关键在于单纯使用分组聚合的话没有办法输出device_id,它只能输出最小的gpa值。所以正确的思路有两种:

  1. 使用连接:建立一个派生表,在派生表中按如上方式分组聚合找到每个学校的最小gpa,然后将原表和派生表进行内连接,连接条件为学校名称和gpa都相等,这样就能找出每个学校最小gpa的记录,并且因为使用了原表连接,可以输出相应的device_id,如果一个学校中有多个同学gpa都恰好等于最小值,则也能一并输出。
  2. 使用窗口函数:本题的问题也可以说是属于TOP N问题,因此可以使用窗口函数解决,使用排名函数RANK()或者DENSE_RANK()都行,给每一行分配一个编号,但是注意不能使用ROW_NUMBER(),ROW_NUMBER()的编号是不重复的,假如最低gpa有多名同分同学,ROW_NUMBER()会给这些同分同学依次编号为1、2、3...,最后无法筛选出所有同分同学,而RANK()和DENSE_RANK()都会给相同gpa的同学分配同样的编号。窗口规则设定为按university分组,按gpa升序排序,这样每个学校最低的gpa的同学会被分配序号1,之后取出所有序号为1的同学即可。需要注意窗口函数列没法直接在WHERE子句中使用,因此也需要通过派生表来进行查询。

代码及解释:

由于本题归类在窗口函数知识点中,因此展示窗口函数解题代码:

SELECT
    device_id,
    university,
    gpa
FROM
    (
        SELECT 
            device_id,
            university,
            gpa,
            RANK() OVER (PARTITION BY university ORDER BY gpa) AS rk
        FROM
            user_profile
    ) AS t
WHERE
    rk = 1
ORDER BY
	university;

在FROM子句后面创建派生表,在派生表中使用窗口函数给所有学生排名,窗口规则设定为按university分组:PARTITION BY university、组内按gpa升序排列:ORDER BY gpa,给排序列设置列别名rk,给派生表设置临时表名t,最后在外层查询中限定rk = 1,即可找出每个学校中所有gpa最低的同学。

ORDER BY university在本题中加不加都不影响结果的正确,但在实际业务中通常需要加上ORDER BY子句指定结果集的排序规则,这样可以保证结果集的行顺序一定,可复现。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务