使用嵌套查询计算MLB击球率时返回多行而非单行的问题求助
问题分析与解决
你当前查询返回6行的核心原因是WHERE条件里的'BA'是字符串字面量,不是你计算的击球率别名:
- 子查询里的
MAX('BA')实际是在求字符串"BA"的最大值,结果还是"BA"; - 外层的
'BA' = 'BA'这个条件永远为真,所以所有满足teamID='HOU' and yearID=2005 and AB>400的行都会被返回。
对比你之前的本垒打查询,那个查询里的HR是表中真实存在的列名,没有加单引号,子查询的MAX(HR)也是针对列值计算,所以逻辑是对的。但这次的BA是你通过计算得到的别名,SQL里不能直接在WHERE子句中引用列别名,更不能加单引号把它变成字符串。
修正方案一:子查询直接计算最大击球率
把WHERE条件里的字符串'BA'替换成实际的击球率计算公式,同时子查询里也要加上AB>400的过滤(避免计算不符合打数要求的球员):
SELECT namefirst + namelast AS 'Name', (h*1.0)/(CASE WHEN AB=0 THEN 1 ELSE AB END) AS 'BA' FROM vwPlayersBatting WHERE (h*1.0)/(CASE WHEN AB=0 THEN 1 ELSE AB END) = ( SELECT MAX((h*1.0)/(CASE WHEN AB=0 THEN 1 ELSE AB END)) FROM vwPlayersBatting WHERE teamID = 'HOU' AND yearID = 2005 AND AB > 400 ) AND teamID = 'HOU' AND yearID = 2005 AND AB > 400
修正方案二:用窗口函数更简洁高效
如果需要处理并列第一的情况(比如多个球员击球率相同),可以用RANK()窗口函数;如果强制只返回一行,换成ROW_NUMBER()即可:
WITH PlayerBA AS ( SELECT namefirst + namelast AS 'Name', (h*1.0)/(CASE WHEN AB=0 THEN 1 ELSE AB END) AS 'BA', RANK() OVER (ORDER BY (h*1.0)/(CASE WHEN AB=0 THEN 1 ELSE AB END) DESC) AS Rank FROM vwPlayersBatting WHERE teamID = 'HOU' AND yearID = 2005 AND AB > 400 ) SELECT Name, BA FROM PlayerBA WHERE Rank = 1;
内容的提问来源于stack exchange,提问作者hudg
相关产品推荐
相关产品推荐

