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

PostgreSQL多对多表查询:判断指定运动员是否加入班级

解决PostgreSQL中查询每个班级是否包含指定运动员的问题

嘿,我明白你的问题啦!你现在的SQL语句是直接从classes_athletes表逐条查询,所以会返回每一条报名记录的判断结果,而不是每个班级只返回一行。咱们需要调整思路,先拿到所有班级的ID,再逐个判断指定运动员是否报名了这个班级。

这里有两种靠谱的方法可以实现你的需求:

方法一:使用LEFT JOIN + 聚合函数

这个方法先从classes表获取所有班级(确保哪怕没有运动员报名的班级也能被查到),然后左连接classes_athletes表并过滤指定的运动员ID,最后通过聚合函数判断该班级是否存在这个运动员的报名记录:

SELECT 
    c.class_id,
    CAST(MAX(CASE WHEN ca.athlete_id = 1 THEN 1 ELSE 0 END) AS bit) AS athleteIsEnrolled
FROM classes c
LEFT JOIN classes_athletes ca 
    ON c.class_id = ca.class_id AND ca.athlete_id = 1
GROUP BY c.class_id;

原理说明:

  • LEFT JOIN会保留所有班级,不管该班级有没有指定运动员的报名记录
  • 当存在指定运动员的报名时,CASE语句返回1,否则返回0
  • MAX()聚合函数会取出每个班级的最大值,只要有一条匹配记录,结果就是1,否则是0
  • 最后转成bit类型符合你需要的输出格式

方法二:使用EXISTS子查询

这种方法更直观,直接检查每个班级是否存在指定运动员的报名记录,代码更简洁:

SELECT 
    c.class_id,
    CAST(EXISTS (
        SELECT 1 
        FROM classes_athletes ca 
        WHERE ca.class_id = c.class_id AND ca.athlete_id = 1
    ) AS bit) AS athleteIsEnrolled
FROM classes c;

原理说明:

  • EXISTS子查询会判断当前班级是否存在指定运动员的报名记录,返回布尔值true或false
  • 把布尔值转成bit类型后,true会变成1,false变成0,正好是你需要的结果
  • 不需要分组查询,执行效率也很高

这两种方法都能满足你的需求:当指定athlete_id=1时,两个班级都返回1;指定athlete_id=99时,都返回0。

如果你的classes表中没有所有班级的记录(比如有些班级只在classes_athletes里存在),可以把FROM classes c改成FROM (SELECT DISTINCT class_id FROM classes_athletes) c,这样就能覆盖所有有报名记录的班级啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:23:18