SQL查询一对多的关系

时间:2013-03-06 15:45:57

标签: sql join

我有一个Employees表和另一个表 训练。训练表包含各种训练课程 员工已经完成了。我们有强制性的安全意识培训,所以 每个员工都必须完成这个培训课程。我在运行查询时遇到问题,该查询将返回列出完成培训的所有员工。

示例员工表

╔════╦══════╗
║ 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

缺少“安全意识”课程的员工似乎没有出现,并且陷入了困境。

5 个答案:

答案 0 :(得分:15)

使用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

RESULT

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

答案 1 :(得分:1)

您正在执行内部联接,您想要的是左外部联接。不同之处在于:内部联接将结果,其中联接表中存在匹配。左外连接将返回主表中的所有结果,无论连接表中是否有结果。

答案 2 :(得分:1)

而不是JOIN使用LEFT OUTER JOIN。我还将你的WHERE子句改为

WHERE training.Id = 1

如果相当于

答案 3 :(得分: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

答案 4 :(得分: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