NFL联盟网站自动季后赛排名SQL查询需求及问题求助
解决NFL NFC季后赛排名的SQL实现问题
我来帮你搞定这个自动排名的需求,先拆解你的两个核心目标,再一步步修正你的SQL语句:
一、获取每个NFC分区的胜场最高球队
你的原SQL语句存在两个关键问题:
GROUP BY division但SELECT team不符合SQL标准(除非数据库启用了宽松模式),数据库会随机返回分区内的某支球队,无法保证和Max(win)对应;- 即使返回了球队,
Max(win)只是分区的最高胜场,但不一定是该球队的实际胜场,结果会失真。
推荐使用窗口函数来精准获取每个分区的头名,这是处理分组内Top N场景的最优方案:
WITH nfc_teams_ranked AS ( SELECT team, win, loss, -- 按分区分组,胜场降序排名,每个分区的第一名rn=1 ROW_NUMBER() OVER (PARTITION BY division ORDER BY win DESC) AS rank_in_division FROM db WHERE conf = 'nfc' ) SELECT team, win, loss FROM nfc_teams_ranked WHERE rank_in_division = 1;
补充说明:
- 如果分区内有多支球队胜场相同(并列第一),
ROW_NUMBER()会随机选一支;如果需要保留所有并列球队,把ROW_NUMBER()换成RANK()即可。 - 这个CTE(公共表表达式)会先给每个分区的球队按胜场排序,再筛选出排名第一的球队,确保球队和战绩完全对应。
二、获取非分区头名中的胜场前2球队
基于上面的CTE,我们可以直接排除分区头名,再按胜场排序取前两名:
WITH nfc_teams_ranked AS ( SELECT team, win, loss, ROW_NUMBER() OVER (PARTITION BY division ORDER BY win DESC) AS rank_in_division FROM db WHERE conf = 'nfc' ), non_division_leaders AS ( SELECT team, win, loss FROM nfc_teams_ranked WHERE rank_in_division > 1 -- 排除分区头名 ) SELECT team, win, loss FROM non_division_leaders ORDER BY win DESC LIMIT 2;
合并查询(可选)
如果你想一次性获取分区头名和外卡球队,可以用UNION ALL把两个结果集合并,加上类型标记区分:
WITH nfc_teams_ranked AS ( SELECT team, win, loss, ROW_NUMBER() OVER (PARTITION BY division ORDER BY win DESC) AS rank_in_division FROM db WHERE conf = 'nfc' ) SELECT 'Division Leader' AS type, team, win, loss FROM nfc_teams_ranked WHERE rank_in_division = 1 UNION ALL SELECT 'Wild Card' AS type, team, win, loss FROM ( SELECT team, win, loss FROM nfc_teams_ranked WHERE rank_in_division > 1 ORDER BY win DESC LIMIT 2 ) AS wild_cards ORDER BY type, win DESC;
这样就能清晰区分分区头名和外卡球队了。
内容的提问来源于stack exchange,提问作者Stu Parker
相关产品推荐
相关产品推荐

