带连接的子查询语法修复:关联求和字段至主SQL查询
排查子查询语法错误&整合求和字段解决方案
让我帮你拆解一下子查询里的问题,你确实猜对了核心问题出在子查询的FROM/JOIN语法上,还有一些逻辑细节需要调整:
你的简化SQL里的几个关键错误
- 括号与别名位置错误
你把别名AS tt放在了ON tbl_Ts_mkv_atp.ID_Ts = tbl_Ts_base_atp.ID_Ts后面,这是语法错误。别名应该绑定在你要命名的表(或表组合)末尾,而且你的JOIN括号没有正确闭合,导致数据库无法解析表关系。 - 冗余关联主表
子查询里没必要再次JOINtoday_atp,这会让关联逻辑混乱。子查询只需要通过tbl_Ts_base_atp.ID_T和主查询的today_atp.TOUR做关联即可。 - 多余的ORDER BY
标量子查询只需要返回单个聚合值,ORDER BY在这里完全没用,反而可能引发语法报错。
修正后的简化版SQL
SELECT today_atp.TOUR, ( SELECT Sum(tbl_Ts_mkv_atp.FS) FROM tbl_Ts_base_atp INNER JOIN tbl_Ts_mkv_atp ON tbl_Ts_base_atp.ID_Ts = tbl_Ts_mkv_atp.ID_Ts WHERE tbl_Ts_base_atp.DATE_T > Date()-2000 AND tbl_Ts_base_atp.DATE_T < Date() AND tbl_Ts_base_atp.ID_T = today_atp.TOUR -- 关联主查询的TOUR字段 GROUP BY tbl_Ts_base_atp.ID_T -- 确保每个ID_T返回唯一求和值 ) AS SumOfFS FROM today_atp
整合到原主查询的完整SQL(标量子查询方式)
SELECT tours_atp.NAME_T, today_atp.TOUR, today_atp.ID1, odds_atp.K1, today_atp.ID2, odds_atp.K2, ( SELECT Sum(tbl_Ts_mkv_atp.FS) FROM tbl_Ts_base_atp INNER JOIN tbl_Ts_mkv_atp ON tbl_Ts_base_atp.ID_Ts = tbl_Ts_mkv_atp.ID_Ts WHERE tbl_Ts_base_atp.DATE_T > Date()-2000 AND tbl_Ts_base_atp.DATE_T < Date() AND tbl_Ts_base_atp.ID_T = today_atp.TOUR GROUP BY tbl_Ts_base_atp.ID_T ) AS SumOfFS FROM (players_atp INNER JOIN (players_atp AS players_atp_1 INNER JOIN (today_atp INNER JOIN odds_atp ON (today_atp.TOUR = odds_atp.ID_T_O) AND (today_atp.ID1 = odds_atp.ID1_O) AND (today_atp.ID2 = odds_atp.ID2_O) AND (today_atp.ROUND = odds_atp.ID_R_O) ) ON players_atp_1.ID_P = today_atp.ID2 ) ON players_atp.ID_P = today_atp.ID1) INNER JOIN tours_atp ON today_atp.TOUR = tours_atp.ID_T WHERE (((tours_atp.RANK_T) Between 1 And 4) AND ((today_atp.RESULT)="") AND ((players_atp.NAME_P) Not Like "*/*") AND ((players_atp_1.NAME_P) Not Like "*/*") AND ((odds_atp.ID_B_O)=2)) ORDER BY tours_atp.NAME_T;
更高效的派生表JOIN方式(推荐大数据量场景)
如果你的数据量较大,用派生表+LEFT JOIN的方式性能会更好,避免逐行执行子查询:
SELECT tours_atp.NAME_T, today_atp.TOUR, today_atp.ID1, odds_atp.K1, today_atp.ID2, odds_atp.K2, COALESCE(fs_sum.SumOfFS, 0) AS SumOfFS -- 无匹配时返回0而非NULL FROM (players_atp INNER JOIN (players_atp AS players_atp_1 INNER JOIN (today_atp INNER JOIN odds_atp ON (today_atp.TOUR = odds_atp.ID_T_O) AND (today_atp.ID1 = odds_atp.ID1_O) AND (today_atp.ID2 = odds_atp.ID2_O) AND (today_atp.ROUND = odds_atp.ID_R_O) ) ON players_atp_1.ID_P = today_atp.ID2 ) ON players_atp.ID_P = today_atp.ID1) INNER JOIN tours_atp ON today_atp.TOUR = tours_atp.ID_T LEFT JOIN ( SELECT tbl_Ts_base_atp.ID_T, Sum(tbl_Ts_mkv_atp.FS) AS SumOfFS FROM tbl_Ts_base_atp INNER JOIN tbl_Ts_mkv_atp ON tbl_Ts_base_atp.ID_Ts = tbl_Ts_mkv_atp.ID_Ts WHERE tbl_Ts_base_atp.DATE_T > Date()-2000 AND tbl_Ts_base_atp.DATE_T < Date() GROUP BY tbl_Ts_base_atp.ID_T ) AS fs_sum ON fs_sum.ID_T = today_atp.TOUR WHERE (((tours_atp.RANK_T) Between 1 And 4) AND ((today_atp.RESULT)="") AND ((players_atp.NAME_P) Not Like "*/*") AND ((players_atp_1.NAME_P) Not Like "*/*") AND ((odds_atp.ID_B_O)=2)) ORDER BY tours_atp.NAME_T;
内容的提问来源于stack exchange,提问作者Jossy




