SQL Server中如何筛选最优项目奖牌数超过其他项目总和的国家?
解决奥运会国家奖牌项目占比问题
首先得指出你之前语句的核心问题:你在WHERE里嵌套了MAX(SUM(...)),这在SQL里是不允许的——聚合函数(比如SUM、MAX)不能直接放在WHERE子句中,而且你的分组维度也偏了,我们最终要按国家来分组统计,而非项目。
下面我们一步步拆解需求,给出可执行的解决方案:
步骤1:计算每个国家每个项目的总奖牌数
先关联三张表,按国家(Nationality)和项目(Discipline)分组,统计每个国家在单个项目上的累计奖牌数:
WITH CountryDisciplineMedals AS ( SELECT a.Nationality, d.Discipline, SUM(m.Medals) AS TotalMedalsPerDiscipline FROM dbo.Athletes a JOIN dbo.Medals m ON a.AthleteID = m.AthleteID JOIN dbo.Dysciplines d ON a.DisciplineID = d.DisciplineID GROUP BY a.Nationality, d.Discipline ),
步骤2:计算每个国家的总奖牌数和最优项目奖牌数
基于上面的结果,对每个国家计算两个关键值:一是该国所有项目的总奖牌数,二是该国奖牌最多的项目(最优项目)的奖牌数:
CountryTotalAndMax AS ( SELECT Nationality, SUM(TotalMedalsPerDiscipline) AS TotalMedals, MAX(TotalMedalsPerDiscipline) AS MaxDisciplineMedals FROM CountryDisciplineMedals GROUP BY Nationality )
步骤3:筛选满足条件的国家
最后筛选出「最优项目奖牌数 > 其他所有项目奖牌数总和」的国家,这个条件等价于MaxDisciplineMedals * 2 > TotalMedals(因为其他项目总和=总奖牌数-最优项目奖牌数):
SELECT Nationality FROM CountryTotalAndMax WHERE MaxDisciplineMedals > TotalMedals - MaxDisciplineMedals ORDER BY Nationality;
完整可执行SQL
把以上步骤整合起来,就是完整的查询语句:
WITH CountryDisciplineMedals AS ( SELECT a.Nationality, d.Discipline, SUM(m.Medals) AS TotalMedalsPerDiscipline FROM dbo.Athletes a JOIN dbo.Medals m ON a.AthleteID = m.AthleteID JOIN dbo.Dysciplines d ON a.DisciplineID = d.DisciplineID GROUP BY a.Nationality, d.Discipline ), CountryTotalAndMax AS ( SELECT Nationality, SUM(TotalMedalsPerDiscipline) AS TotalMedals, MAX(TotalMedalsPerDiscipline) AS MaxDisciplineMedals FROM CountryDisciplineMedals GROUP BY Nationality ) SELECT Nationality FROM CountryTotalAndMax WHERE MaxDisciplineMedals > TotalMedals - MaxDisciplineMedals ORDER BY Nationality;
补充说明
- 这里用了**CTE(公用表表达式)**来拆分逻辑,让代码更易读,你也可以用嵌套子查询替代,但CTE的可读性更优。
- 如果某个国家只有一个参赛项目,那么它的其他项目奖牌总和为0,会自动被纳入结果中,符合需求逻辑。
- 你原语句的错误核心:聚合函数不能嵌套使用(比如
MAX(SUM(...))),且分组维度不符合最终统计目标——我们需要先按「国家+项目」细化统计,再按「国家」汇总判断。
内容的提问来源于stack exchange,提问作者Alphanovamax22
相关产品推荐
相关产品推荐

