You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Inner Join按指定年份范围SUM AB字段时求和异常的技术问询

问题:仅统计球员生涯特定年份范围的AB字段总和失败

我有两张表:

  • Batting表:记录球员各年份数据,包含Year字段(smallint类型)
  • Person表:包含球员的DebutYear(出道年份)和FinalYear(退役年份)字段(均为smallint类型)

我想统计Batting表中处于DebutYear+1至DebutYear+2范围内的年份的AB字段总和,但当前写的SQL却把Batting表中所有年份的AB都求和了,求帮忙修正。

原错误SQL

SELECT CONCAT(FirstName, ' ', LastName) AS Name, B.PersonID, SUM(AB) AS AB
  FROM Batting B
  INNER JOIN Person P ON P.PersonID = B.PersonID
    AND (B.Year >= (P.DebutYear+1) AND B.Year <= (P.DebutYear+2))
  WHERE B.PersonID = P.PersonID 
  GROUP BY B.PersonID
  HAVING (AB >= 10000)
  ORDER BY AB Desc, LastName, FirstName
  LIMIT 1000

示例数据

Person表

PersonIDNameDebutYear
rosepe01Pete Rose1963

Batting表

BattingPersonIDYearAB
1rosepe011963623
2rosepe011964516
3rosepe011965670
4rosepe011966654
5rosepe011967585
6rosepe011968626

修正后的SQL

SELECT CONCAT(FirstName, ' ', LastName) AS Name, B.PersonID, SUM(AB) AS TotalAB
FROM Batting B
INNER JOIN Person P 
    ON P.PersonID = B.PersonID
    AND B.Year BETWEEN (P.DebutYear + 1) AND (P.DebutYear + 2)
GROUP BY B.PersonID, FirstName, LastName
HAVING SUM(AB) >= 10000
ORDER BY TotalAB DESC, LastName, FirstName
LIMIT 1000

修正说明

  1. 移除多余条件:删掉WHERE B.PersonID = P.PersonID,INNER JOIN的ON条件已经完成两张表的关联,重复写无意义。
  2. 规范GROUP BY:将FirstName和LastName加入GROUP BY,符合SQL标准,避免因模式设置导致的报错或结果异常。
  3. 优化条件写法:用BETWEEN替代范围判断,逻辑不变但更简洁。
  4. 避免别名混淆:将聚合结果的别名改为TotalAB,和原表的AB字段区分开;同时HAVING直接使用SUM(AB),避免部分SQL方言不支持在HAVING中使用聚合别名的问题。
  5. 关于求和范围错误的原因:你误以为所有年份被求和,大概率是因为原HAVING条件AB >= 10000过滤掉了符合目标年份的小数据(比如示例中Pete Rose的目标年份总和仅1186,远低于10000),而如果存在球员所有年份AB总和刚好达标,就会让你产生误解。修正后的SQL会严格只统计DebutYear+1到DebutYear+2的AB总和。

内容的提问来源于stack exchange,提问作者studebaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:42:10