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

基于唯一ID遍历表,查询学员未完成培训记录的SQL需求

解决方案

核心思路

要找出所有学员未完成的培训,首先需要生成所有学员与所有培训的全量组合(即每个学员理论上需要完成的所有培训),再从中排除已经完成(result=1)的记录,剩下的就是未完成的培训(包括从未参加的培训、参加但未通过的培训)。


形式1:输出nameid和typeid

可以用NOT EXISTS子查询直接排除已完成的记录:

SELECT n.nameid, t.typeid
FROM names n
CROSS JOIN training t
WHERE NOT EXISTS (
    SELECT 1
    FROM log l
    WHERE l.nameid = n.nameid
      AND l.typeid = t.typeid
      AND l.result = 1
)
ORDER BY n.nameid, t.typeid;

也可以用LEFT JOIN实现逻辑等价的查询:

SELECT n.nameid, t.typeid
FROM names n
CROSS JOIN training t
LEFT JOIN log l 
  ON l.nameid = n.nameid 
  AND l.typeid = t.typeid 
  AND l.result = 1
WHERE l.nameid IS NULL
ORDER BY n.nameid, t.typeid;

形式2:输出学员姓名与培训类型名称

只需在上述查询基础上,直接关联表中的名称字段即可:

SELECT n.name, t.training_name
FROM names n
CROSS JOIN training t
WHERE NOT EXISTS (
    SELECT 1
    FROM log l
    WHERE l.nameid = n.nameid
      AND l.typeid = t.typeid
      AND l.result = 1
)
ORDER BY n.name, t.training_name;

关键说明

  • CROSS JOIN的作用是生成学员与培训的全量组合,确保不会遗漏任何学员需要完成的培训项。
  • 如果log表中存在同一学员同一培训的多条记录,只要有一条result=1,就会被视为已完成并排除。
  • 若业务中需要区分“未参加”和“已参加未通过”,可以扩展查询显示状态:
    SELECT 
        n.name, 
        t.training_name,
        CASE 
            WHEN l.result = 0 THEN '已参加未通过'
            ELSE '未参加'
        END AS status
    FROM names n
    CROSS JOIN training t
    LEFT JOIN log l 
      ON l.nameid = n.nameid 
      AND l.typeid = t.typeid
    WHERE l.result IS NULL OR l.result = 0
    ORDER BY n.name, t.training_name;
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:06:08