如何在GROUP BY查询中获取POSITION、NAME及各位置最高身高球员信息
问题描述
现有TEAM表的结构和数据如下:
POSITION NAME HEIGHT ________ _________ ______ GK Jhon 178 GK Steven 190 DF Paul 183 DF Andrew 178 DF Nick 169 MF Ali 170 MF Peter 176 MF Charlie 180 FW Simon 185 FW Son 184 FW Jack 179
需求是查询每个位置(POSITION)里身高最高的球员,要同时返回位置、姓名和身高,期望结果如下:
POSITION NAME HEIGHT ________ _________ ______ GK Steven 190 DF Paul 183 MF Charlie 180 FW Simon 185
之前执行SELECT POSITION, MAX(HEIGHT) FROM TEAM GROUP BY POSITION;只能拿到位置和对应最高身高,缺少球员姓名,下面是几种补全姓名的实现方法。
解决方案
方法1:子查询关联
先分组算出每个位置的最高身高,再和原表关联匹配出对应的球员:
SELECT t.POSITION, t.NAME, t.HEIGHT FROM TEAM t JOIN ( SELECT POSITION, MAX(HEIGHT) AS max_height FROM TEAM GROUP BY POSITION ) t_max ON t.POSITION = t_max.POSITION AND t.HEIGHT = t_max.max_height;
这种方法适配所有支持标准SQL的数据库,逻辑简单直接:先拿到各位置的最高身高数据,再通过「位置+身高」的组合条件,从原表中找到对应的球员记录。
方法2:窗口函数排名
用窗口函数给每个位置的球员按身高降序排号,取排名第一的记录:
SELECT POSITION, NAME, HEIGHT FROM ( SELECT POSITION, NAME, HEIGHT, ROW_NUMBER() OVER (PARTITION BY POSITION ORDER BY HEIGHT DESC) AS rn FROM TEAM ) t WHERE rn = 1;
如果同一个位置有多个球员身高并列最高,ROW_NUMBER()会随机选其中一个;要是想保留所有并列最高的球员,把ROW_NUMBER()换成RANK()或者DENSE_RANK()即可。
方法3:自连接筛选
通过自连接,筛选出同位置里没有比他更高的球员:
SELECT t1.POSITION, t1.NAME, t1.HEIGHT FROM TEAM t1 LEFT JOIN TEAM t2 ON t1.POSITION = t2.POSITION AND t2.HEIGHT > t1.HEIGHT WHERE t2.POSITION IS NULL;
逻辑是:给每个球员找同位置里身高比他高的人,如果找不到这样的人,说明他就是该位置身高最高的。这种方法会自动保留所有并列最高的球员。
内容的提问来源于stack exchange,提问作者KGB
相关产品推荐
相关产品推荐

