MySQL多表JOIN查询:按指定training_id查询全量员工及对应培训情况
问题原因
你原SQL的问题出在将th.training_id = 1写在了WHERE子句中,该条件会过滤掉所有关联后training_id为NULL的行,相当于把左连接转为了内连接,自然无法返回未参加指定培训的员工记录。
筛选条件如果写在左连接的ON子句中,只会作用于关联的右表,不会过滤左表的全量数据,没匹配到的记录相关字段自动返回NULL,正好匹配你的需求。
正确写法
有两种常用实现方案,都可以保留全量员工数据,仅关联指定培训的参与信息:
方案1:将培训ID筛选条件写入JOIN的ON子句
SELECT emp.employee_name AS employee, trn.training_name AS training FROM employees AS emp LEFT JOIN training_histories AS th ON emp.id = th.employee_id AND th.training_id = ? -- 此处替换为你传入的training_id参数 LEFT JOIN trainings AS trn ON th.training_id = trn.id;
方案2:先过滤培训参与表再关联(可读性更高)
SELECT emp.employee_name AS employee, trn.training_name AS training FROM employees AS emp LEFT JOIN ( -- 先筛选出指定培训的所有参与记录,再和员工表关联 SELECT * FROM training_histories WHERE training_id = ? ) AS th ON emp.id = th.employee_id LEFT JOIN trainings AS trn ON th.training_id = trn.id;
注意事项
你原SQL中使用的表名employee_training_histories、字段名emp_id和你给出的表结构定义不一致,实际执行时请替换为你环境中的真实表名、字段名。
内容的提问来源于stack exchange,提问作者Gunawan Suarna
相关产品推荐
相关产品推荐

