You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL多表关联查询问题:获取所有球员及下一次训练信息

解决方案:获取所有球员信息及最近未来训练日期

我完全理解你的需求——要拿到每一位球员的完整信息,包括他们当前日期之后的最近一次训练(如果有的话),就算没有未来训练,也不能把球员信息漏掉。你之前的SQL之所以达不到要求,核心问题出在这两点:

  1. 用了WHERE training.start_date > CURRENT_DATE过滤,这会直接把LEFT JOIN后training相关字段为NULL的球员(也就是没有未来训练的)排除掉,因为NULL > CURRENT_DATE的结果是UNKNOWN,WHERE子句只会保留条件为TRUE的行;
  2. GROUP BY的用法不规范,会导致查询结果出现不确定的字段值(除非你用的是MySQL的非严格模式)。

下面给你两种可行的解决方案,都能满足你的需求:

方法一:使用窗口函数(推荐,可读性和性能都不错)

窗口函数可以很方便地给每个球员的未来训练排序,直接取最近的那一条:

SELECT 
    t.id_team,
    p.id_player,
    tr.id_training,
    p.name AS player_name,
    p.age,
    tr.start_date
FROM Player p
-- 关联球员所属球队
JOIN Team_Player tp ON p.id_player = tp.id_player
JOIN Team t ON tp.id_team = t.id_team
-- 左关联筛选出的每个球员的最近未来训练
LEFT JOIN (
    SELECT 
        id_training,
        id_player,
        start_date,
        -- 按球员分组,训练日期升序排序,最近的训练排第1
        ROW_NUMBER() OVER (PARTITION BY id_player ORDER BY start_date ASC) AS rn
    FROM Training
    -- 只筛选当前日期之后的训练
    WHERE start_date > CURRENT_DATE
) tr ON p.id_player = tr.id_player AND tr.rn = 1
-- 按球员ID排序,方便查看
ORDER BY p.id_player;

方法二:使用关联子查询

如果你的数据库不支持窗口函数(比如一些旧版本的数据库),可以用关联子查询来获取每个球员的最近未来训练日期,再关联Training表:

SELECT 
    t.id_team,
    p.id_player,
    tr.id_training,
    p.name AS player_name,
    p.age,
    tr.start_date
FROM Player p
JOIN Team_Player tp ON p.id_player = tp.id_player
JOIN Team t ON tp.id_team = t.id_team
-- 左关联训练表,只匹配当前球员最近的未来训练
LEFT JOIN Training tr 
    ON p.id_player = tr.id_player 
    AND tr.start_date = (
        -- 子查询获取当前球员的最近未来训练日期
        SELECT MIN(start_date) 
        FROM Training 
        WHERE id_player = p.id_player AND start_date > CURRENT_DATE
    )
ORDER BY p.id_player;

这两种方法都会返回你期望的结果:没有未来训练的球员,对应的id_training和start_date会显示为NULL,同时保留所有球员的基础信息和所属球队信息。

内容的提问来源于stack exchange,提问作者Erwan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:39:57