SQLZoo JOIN操作练习问题排查:LEFT JOIN多表关联主表时Score2列结果异常
问题分析与修正方案
我明白你碰到的问题了——你的查询里SCORE2和SCORE1结果完全一致,这其实是因为两次LEFT JOIN关联GOAL表时产生了笛卡尔积,导致计数逻辑失效了。
错误原因拆解
当你分别用X和Y两次关联GOAL表时,TEAM1的每一个进球记录都会和TEAM2的每一个进球记录匹配,形成多条重复的组合记录。比如如果TEAM1进了2球、TEAM2进了1球,JOIN后会生成2×1=2条记录,这时候COUNT(X.MATCHID)和COUNT(Y.MATCHID)都会统计成2,而不是正确的2和1。
修正后的代码
你可以改用条件聚合的方式,只关联一次GOAL表,然后在聚合时分别统计两队的进球数,这样就能避免笛卡尔积的问题:
SELECT MDATE, TEAM1, COUNT(CASE WHEN TEAMID = TEAM1 THEN 1 END) AS SCORE1, TEAM2, COUNT(CASE WHEN TEAMID = TEAM2 THEN 1 END) AS SCORE2 FROM GAME LEFT JOIN GOAL ON ID = MATCHID GROUP BY MDATE, TEAM1, TEAM2
或者用SUM函数实现,逻辑会更直观:
SELECT MDATE, TEAM1, SUM(CASE WHEN TEAMID = TEAM1 THEN 1 ELSE 0 END) AS SCORE1, TEAM2, SUM(CASE WHEN TEAMID = TEAM2 THEN 1 ELSE 0 END) AS SCORE2 FROM GAME LEFT JOIN GOAL ON ID = MATCHID GROUP BY MDATE, TEAM1, TEAM2
为什么这个方法有效?
通过一次LEFT JOIN关联GOAL表,再用CASE WHEN在聚合阶段分别筛选属于TEAM1和TEAM2的进球记录,每一条进球只会被统计到对应的队伍得分中,不会产生重复计数,自然就能得到准确的SCORE1和SCORE2结果了。
内容的提问来源于stack exchange,提问作者Tamer Gad
相关产品推荐
相关产品推荐

