SQL技术问询:筛选仅参与国际象棋且无其他游戏记录的玩家
解决仅参与国际象棋玩家的查询问题
嘿,刚接触SQL遇到这种筛选问题太正常了,我来给你捋几个靠谱的解法,帮你精准找出只玩国际象棋(chess)、没碰过其他游戏的玩家,还能保证姓名只返回一次!
方法一:用NOT EXISTS排除其他游戏记录
这是最直观的思路——先锁定所有玩过国际象棋的玩家,再排除掉那些有其他游戏记录的人,最后用DISTINCT去重:
SELECT DISTINCT first_name, last_name FROM player_appearances pa1 WHERE game = 'chess' AND NOT EXISTS ( SELECT 1 FROM player_appearances pa2 WHERE pa1.first_name = pa2.first_name AND pa1.last_name = pa2.last_name AND pa2.game != 'chess' );
逻辑拆解:
- 外层查询先筛选出玩过chess的玩家
- 子查询检查同一个玩家是否存在其他游戏的记录,如果不存在(
NOT EXISTS),就保留这个玩家 DISTINCT确保即使一个玩家多次玩chess,姓名也只显示一次
方法二:用GROUP BY + HAVING统计游戏种类
这种方法通过分组统计每个玩家的游戏数量,直接筛选出只玩一种游戏且该游戏是chess的玩家:
SELECT first_name, last_name FROM player_appearances GROUP BY first_name, last_name HAVING COUNT(DISTINCT game) = 1 AND MAX(game) = 'chess';
逻辑拆解:
- 按玩家姓名分组(如果有重名情况,建议加上唯一的玩家ID字段)
COUNT(DISTINCT game) = 1保证这个玩家只玩过一种游戏MAX(game) = 'chess'确认这种游戏就是国际象棋(因为只有一种游戏,MAX/MIN结果都一致)- 这里不需要
DISTINCT,分组后每个姓名只会出现一次
方法三:用LEFT JOIN筛选无其他游戏的记录
通过左连接匹配玩家的其他游戏记录,然后排除有匹配的结果:
SELECT DISTINCT pa1.first_name, pa1.last_name FROM player_appearances pa1 LEFT JOIN player_appearances pa2 ON pa1.first_name = pa2.first_name AND pa1.last_name = pa2.last_name AND pa2.game != 'chess' WHERE pa1.game = 'chess' AND pa2.first_name IS NULL;
逻辑拆解:
- 左连接玩chess的玩家和他们玩其他游戏的记录
- 如果玩家没有其他游戏记录,pa2的字段会是
NULL,通过这个条件筛选出目标玩家 DISTINCT用来避免重复的姓名记录
之前你只筛选game='chess'会包含那些同时玩其他游戏的玩家,以上几种方法都能帮你精准过滤掉这些情况,根据你的表结构和数据量选合适的就行~
内容的提问来源于stack exchange,提问作者Chase Lundell
相关产品推荐
相关产品推荐

