SQL三表连接去重:解决符合条件的球员数据查询异常问题
解决球员数据重复与得分累加异常的问题
问题根源
你遇到的重复行和得分累加错误,本质是球员表与奖项表的一对多关联产生了笛卡尔积——一个球员拿过N个奖项,连接后就会生成N条相同球员信息的记录,得分也会被重复计算N次。
三种可行解决方案
1. 用EXISTS子句筛选(最简洁高效)
这种方式只检查球员是否存在获奖记录,不会产生冗余行,性能也更优:
SELECT p.player_id, p.player_name, p.career_points FROM players p WHERE p.career_points >= 30000 AND p.is_alive = 1 -- 替换成你实际标识"在世"的字段 AND EXISTS ( SELECT 1 FROM awards a WHERE a.player_id = p.player_id );
2. 分组聚合去重(需展示奖项信息时用)
如果要同时展示球员的奖项列表,通过GROUP BY合并重复行,用聚合函数确保得分只取一次:
SELECT p.player_id, p.player_name, p.career_points, -- 同一球员得分唯一,直接取即可,也可以用MAX()/MIN()保险 GROUP_CONCAT(DISTINCT a.award_name SEPARATOR ', ') AS won_awards, COUNT(a.award_id) AS award_count FROM players p JOIN awards a ON p.player_id = a.player_id WHERE p.career_points >= 30000 AND p.is_alive = 1 GROUP BY p.player_id, p.player_name, p.career_points;
3. 先提取唯一获奖球员ID再关联
先从奖项表拿到所有拿过奖的球员ID(去重),再和球员表关联,避免笛卡尔积:
SELECT p.player_id, p.player_name, p.career_points FROM players p INNER JOIN ( SELECT DISTINCT player_id FROM awards ) unique_award_players ON p.player_id = unique_award_players.player_id WHERE p.career_points >= 30000 AND p.is_alive = 1;
关键注意点
- 不要直接用
JOIN奖项表后不做任何去重/分组操作,一对多关系必然导致行重复 - 如果需要统计奖项数量,一定要用
COUNT(DISTINCT a.award_id),避免同一奖项重复计数(比如同一奖项多次颁发的情况)
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

