




本文介绍如何将原本分两步执行的 sql 查询(先查球队列表,再为每个球队单独查最新赛事)合并为一条高效 sql,通过 left join 与 group b
y 配合聚合函数 max() 实现一次性获取所有球队及其最近一场已结束比赛(ft/pen/aet)的时间。
在实际开发中,嵌套循环查询(如 foreach 中反复执行子查询)极易引发“N+1 查询问题”,显著降低性能并增加数据库负载。针对您原始逻辑——先获取全部球队,再为每支队伍单独查询其最近一场状态为 'FT'、'PEN' 或 'AET' 的赛事——完全可通过单条 SQL 优化实现。
核心思路是:以 teams 表为主表,左连接 events 表,并利用条件关联(home_team = teams.id OR away_team = teams.id),再通过 GROUP BY teams.id 对每支队伍聚合,最后用 MAX(events.time) 提取该队所有匹配赛事中的最新时间。
以下是优化后的完整 SQL:
SELECT
teams.id,
teams.name,
teams.updated,
MAX(events.time) AS latest_time
FROM teams
LEFT JOIN events
ON events.home_team = teams.id
OR events.away_team = teams.id
WHERE
events.status IN ('FT', 'PEN', 'AET')
OR events.status IS NULL -- 保留无匹配赛事的球队(LEFT JOIN 的意义)
GROUP BY teams.id, teams.name, teams.updated
ORDER BY teams.name ASC;✅ 关键说明:
? 进阶建议:若需获取整条最新赛事记录(不止 time 字段),则需改用窗口函数(MySQL 8.0+)或相关子查询,但当前场景中 MAX() 已精准满足需求,简洁且高效。
综上,该单查询不仅消除循环开销,还提升可维护性与可读性,是典型的关系型数据库“以集合思维替代过程思维”的最佳实践。