编写正确SQL查询:获取所有与女性球员一同踢足球的男性人员姓名
修正SQL查询:找出和女性一同踢足球的男性球员
嘿,我一眼就看出你原来的查询哪里出问题了!让我一步步帮你修正:
原查询的两大问题
- 没限定运动类型:你要找的是「一同踢足球」的搭档,但原查询里完全没筛选
sport = 'football',会把所有运动的配对都算进去 - 错误关联表:你用了两张独立的
SportTogether表(S1和S2),但没把它们关联起来——这相当于把所有男性球员和所有女性球员做了无意义的配对,不管他们是不是真的一起踢过球,自然会出现错误结果
修正后的查询(两种常用写法)
写法1:用JOIN清晰关联搭档
这种写法直观,把球员和他们的搭档通过同一条运动记录关联起来:
SELECT DISTINCT p.name FROM Persons p JOIN SportTogether s ON (p.id = s.personA_id OR p.id = s.personB_id) JOIN Persons partner ON ( (s.personA_id = partner.id AND p.id = s.personB_id) OR (s.personB_id = partner.id AND p.id = s.personA_id) ) WHERE p.gender = 'male' AND partner.gender = 'female' AND s.sport = 'football';
写法2:用EXISTS更高效
如果你的数据量较大,EXISTS的写法通常更快,因为它找到符合条件的搭档就会停止查找:
SELECT DISTINCT p.name FROM Persons p WHERE p.gender = 'male' AND EXISTS ( SELECT 1 FROM SportTogether s JOIN Persons partner ON partner.id = CASE WHEN s.personA_id = p.id THEN s.personB_id ELSE s.personA_id END WHERE (s.personA_id = p.id OR s.personB_id = p.id) AND partner.gender = 'female' AND s.sport = 'football' );
为什么这样能解决问题?
- 我们确保了男性球员和女性球员是同一条
SportTogether记录里的搭档,而不是随便从两张表凑出来的 - 加上了
s.sport = 'football'的条件,精准限定了踢足球的场景 - 用
DISTINCT避免同一个男性球员如果和多个女性搭档踢球时重复出现
内容的提问来源于stack exchange,提问作者ramos




