SQL中如何根据两列最大值位置选取对应列的比赛日期值
报错原因
你触发的#1111(分组函数使用无效)错误,核心原因是聚合函数不能直接写在WHERE子句中做单行判断:MAX()是对多行数据做统计的聚合类函数,WHERE子句执行时还未完成多行数据的聚合计算,直接调用就会抛出该错误。
除此之外你的原语句还有逻辑缺陷:没有区分得分归属,直接取两个得分字段的全局最大值,拿到的不是目标球员CR7的个人单场得分;且GREATEST()仅返回计算值,没有和当前行的字段做等值比较,本身也无法作为过滤条件。
正确实现方案
核心逻辑分两步:
- 先筛选出CR7参与的所有比赛,统一计算他每场的个人得分:他以
id_jogador1身份参赛时取pontuacao_jog1为个人得分,以id_jogador2身份参赛时取pontuacao_jog2为个人得分 - 找到CR7个人得分的最高值,匹配返回对应的
data_jogo比赛日期
兼容所有SQL版本的写法
该写法不需要高阶语法支持,所有关系型数据库都可以正常运行:
SELECT data_jogo AS Date FROM partidas WHERE (id_jogador1 = 'CR7' AND pontuacao_jog1 = ( SELECT MAX(CASE WHEN id_jogador1 = 'CR7' THEN pontuacao_jog1 ELSE pontuacao_jog2 END) FROM partidas WHERE id_jogador1 = 'CR7' OR id_jogador2 = 'CR7' )) OR (id_jogador2 = 'CR7' AND pontuacao_jog2 = ( SELECT MAX(CASE WHEN id_jogador1 = 'CR7' THEN pontuacao_jog1 ELSE pontuacao_jog2 END) FROM partidas WHERE id_jogador1 = 'CR7' OR id_jogador2 = 'CR7' ));
支持CTE的数据库简化写法
MySQL 8.0及以上、PostgreSQL、SQL Server等支持公用表表达式(CTE)的环境,可以用更清晰的写法实现:
WITH player_match_score AS ( SELECT data_jogo, -- 统一计算CR7本场个人得分 CASE WHEN id_jogador1 = 'CR7' THEN pontuacao_jog1 ELSE pontuacao_jog2 END AS personal_score FROM partidas WHERE id_jogador1 = 'CR7' OR id_jogador2 = 'CR7' ) SELECT data_jogo AS Date FROM player_match_score WHERE personal_score = (SELECT MAX(personal_score) FROM player_match_score);
注:如果CR7有多场比赛都拿到了个人职业生涯最高得分,上述语句会返回所有符合条件的比赛日期,符合数据查询的常规预期。
内容的提问来源于stack exchange,提问作者JoaoR
相关产品推荐
相关产品推荐

