SQL查询优化:获取未提交赛事结果的用户邮箱
问题
需要从Fixtures表筛选符合IsResult=0、Status=1、Date<=CURDATE()条件的赛事,并获取所有未提交对应赛事结果的团队用户邮箱。现有两个查询均存在逻辑缺陷:
- 第一个查询仅返回两队均未提交结果的赛事,无法单独定位某一队未提交的用户
- 第二个查询仅处理主队场景,且在两队均未提交时仅返回一位用户
数据表结构
| 表名 | 字段列表 |
|---|---|
| Users | UserID | TeamID | Email |
| Teams | TeamID | TeamName |
| Fixtures | FixtureID | HomeTeam | AwayTeam | Date | Status | IsResult |
| Results | ResultID | FixtureID | TeamID |
现有查询的问题分析
- 第一个查询:通过两次INNER JOIN直接关联主客队用户,同时用
NOT EXISTS判断两队都未提交结果,导致只有两队均未提交的赛事才会被返回,无法单独列出某一队未提交的用户。 - 第二个查询:仅关联了主队(
f.HomeTeam = t.TeamID),完全忽略客队的未提交情况;且冗余关联了Teams表(Users表已包含TeamID,无需额外关联),逻辑覆盖不完整。
修正后的查询方案
核心思路是将赛事的主客队拆分为独立条目,分别判断每个团队是否未提交结果,确保所有未提交的用户都能被列出。以下是两种可行方案:
方案1:使用UNION ALL拆分主客队逻辑
-- 主队未提交结果的用户 SELECT u.Email, u.UserID, u.TeamID, f.FixtureID, f.Date, f.HomeTeam, f.AwayTeam, 'Home' AS TeamType FROM Fixtures f INNER JOIN Users u ON f.HomeTeam = u.TeamID WHERE f.IsResult = 0 AND f.Status = 1 AND f.Date <= CURDATE() AND NOT EXISTS ( SELECT 1 FROM Results r WHERE r.FixtureID = f.FixtureID AND r.TeamID = f.HomeTeam ) UNION ALL -- 客队未提交结果的用户 SELECT u.Email, u.UserID, u.TeamID, f.FixtureID, f.Date, f.HomeTeam, f.AwayTeam, 'Away' AS TeamType FROM Fixtures f INNER JOIN Users u ON f.AwayTeam = u.TeamID WHERE f.IsResult = 0 AND f.Status = 1 AND f.Date <= CURDATE() AND NOT EXISTS ( SELECT 1 FROM Results r WHERE r.FixtureID = f.FixtureID AND r.TeamID = f.AwayTeam ) ORDER BY f.Date, TeamType;
方案2:使用CROSS JOIN生成主客队列表
SELECT u.Email, u.UserID, u.TeamID, f.FixtureID, f.Date, f.HomeTeam, f.AwayTeam, CASE WHEN t.TeamID = f.HomeTeam THEN 'Home' ELSE 'Away' END AS TeamType FROM Fixtures f -- 生成当前赛事的主客队列表 CROSS JOIN ( SELECT f.HomeTeam AS TeamID UNION ALL SELECT f.AwayTeam AS TeamID ) AS t INNER JOIN Users u ON t.TeamID = u.TeamID WHERE f.IsResult = 0 AND f.Status = 1 AND f.Date <= CURDATE() -- 判断当前团队未提交该赛事结果 AND NOT EXISTS ( SELECT 1 FROM Results r WHERE r.FixtureID = f.FixtureID AND r.TeamID = t.TeamID ) ORDER BY f.Date, TeamType;
方案优势
- 覆盖所有场景:无论单队未提交还是两队均未提交,所有对应用户都会被列出
- 清晰标记:通过
TeamType字段明确区分用户所属的主队/客队,便于定位 - 精准判断:
NOT EXISTS条件针对单个团队+赛事,避免逻辑遗漏 - 去掉冗余关联:无需关联Teams表,直接通过Users表的TeamID关联赛事团队
内容的提问来源于stack exchange,提问作者BN83
相关产品推荐
相关产品推荐

