2013-03-06 172 views
10

我有一个员工表和 培训的另一个表。培训表包含 员工已完成的各种培训课程。我们有强制性的安全意识培训,所以每个员工都必须完成这个培训课程。我在运行查询时遇到问题,这会返回所有员工列出的完成培训或未完成的任务。SQL查询一对多关系

例Employee表

╔════╦══════╗ 
║ ID ║ NAME ║ 
╠════╬══════╣ 
║ 1 ║ Bob ║ 
║ 2 ║ Tom ║ 
║ 3 ║ John ║ 
╚════╩══════╩ 

实例训练表

╔════╦══════════════╦════════════════════╗ 
║ ID ║ DEPARTMENT_ID║  CLASS  ║ 
╠════╬══════════════╬════════════════════╣ 
║ 1 ║   1 ║ Security Awareness ║ 
║ 2 ║   1 ║ Workplace Safety ║ 
║ 3 ║   2 ║ Security Awareness ║ 
╚════╩══════════════╩════════════════════╝ 

目标结果

╔════╦══════╦════════════════════╗ 
║ ID ║ NAME ║  CLASS  ║ 
╠════╬══════╬════════════════════╣ 
║ 1 ║ Bob ║ Security Awareness ║ 
║ 2 ║ Tom ║ Security Awareness ║ 
║ 3 ║ John ║ (null)    ║ 
╚════╩══════╩════════════════════╝ 

,我使用的查询是

SELECT employee.id, employee.name, training.class 
FROM employee 
JOIN training ON employee.id = training.department_id 
WHERE training.class LIKE '%SECURITY%' 
ORDER BY employee_id 

缺少“安全意识”类的员工没有出现,而是落入裂缝中。

+1

是部门标识等于employee.id? – Maciej 2013-03-06 16:06:18

回答

10

使用LEFT JOIN和表进行接合时

另一个(ON条款在具体)移动的过滤条件关注是用单引号:' '不是‘ ’

SELECT employee.id, 
     employee.name, training.class 
FROM employee 
     LEFT JOIN training 
      ON employee.id = training.department_id AND 
       training.class LIKE '%SECURITY%' 
ORDER BY employee.id 

结果

╔════╦══════╦════════════════════╗ 
║ ID ║ NAME ║  CLASS  ║ 
╠════╬══════╬════════════════════╣ 
║ 1 ║ Bob ║ Security Awareness ║ 
║ 2 ║ Tom ║ Security Awareness ║ 
║ 3 ║ John ║ (null)    ║ 
╚════╩══════╩════════════════════╝ 
+3

非常酷,我不知道我可以在连接内过滤。这也将有助于其他领域。 – Rich 2013-03-06 16:36:33

+0

我在这里有另一个解释http://stackoverflow.com/a/15205900/491243 – 2013-03-06 16:38:53

1

你正在执行一个内部连接,你想要的是一个左外部连接。区别在于:内部连接将在处仅有结果,其中连接表中存在匹配。左外连接将返回主表中的所有结果,无论结合表中是否有结果。

+0

一点也不..不会工作 – 2013-03-06 15:51:44

0

你在找什么叫做外部加入。在这种情况下,您需要左外连接:

SELECT employee.id, employee.name, training.class 
FROM employee LEFT OUTER JOIN training ON employee.id = training.department_id 
WHERE training.class LIKE '%Security%' 
ORDER BY employee_id 
0

而不是JOIN使用左外连接。我也想改变你的WHERE子句

WHERE training.Id = 1 

如果这相当于

0
Select e.id, e.name, t.class from employee e left outer join training t on e.id = t.department_id where t.class like '%Security%' order by e.id