替代方法而不是NOT IN

时间:2014-07-31 11:04:33

标签: database

员工表

EmployeeId 

E001         
E002         
E003         
E004         

服务表

ServiceDate     EmployeeId

4/07/2014       E001
3/07/2014       E002
3/01/2014       E004

我想列出从未接受过任何汽车服务的员工的详细信息。

结果应为:

EmployeeId
E003       

我尝试了外连接LEFT OUTER JOIN,但它搞砸了。

4 个答案:

答案 0 :(得分:1)

您可以使用LEFT JOIN代替NOT IN,例如:

select e.* 
from employee e
left join service s on e.employeeid = s.employeeid
where s.employeeid is null

LEFT JOIN确保您获得一个结果集,其中每个员工在Service表中可能有或没有匹配的条目。 WHERE然后过滤结果集,仅保留那些Service中没有相应条目的员工,这等同于您的NOT IN方法。

您应该了解在这种情况下使用子查询没有任何问题,但出于性能原因,使用连接可能更合适。 This问题提供了对连接与子查询的出色分析。

答案 1 :(得分:0)

SELECT * 
FROM Employee e 
WHERE (
      SELECT COUNT(*) 
      FROM service s 
      WHERE e.EmployeeId = s.EmployeeId
      ) = 0;

我不建议这样做。

另一种性能更佳的解决方案(来自Conffusion's comment

SELECT * 
FROM Employee e 
WHERE NOT EXISTS (
      SELECT *
      FROM service s 
      WHERE e.EmployeeId = s.EmployeeId
      );

答案 2 :(得分:0)

没有测试,但我认为它可以工作:

select *
from (select distinct E.*, S.employeeid serviceEmployeeid 
        from employee E left outer join service S on e.employeeid = S.employeeid)
where serviceEmployeeid is null

为单个员工提供多种服务的情况添加了明确的内容。

答案 3 :(得分:0)

我认为这会产生你的解决方案。

SELECT EmployeeId
FROM 
  EMPLOYEE
  LEFT OUTER JOIN
  SERVICE
  ON (EMPLOYEE.EmployeeId = SERVICE.EmployeeId)
WHERE
  SERVICE.ServiceId IS NULL
;