如何用JOIN替换NOT EXISTS?

时间:2014-06-10 15:15:41

标签: mysql sql join output

我收到了以下问题:

select distinct a.id, a.name
from Employee a
join Dependencies b on a.id = b.eid
where not exists 
    ( 
select * 
    from Dependencies d 
    where b.id = d.id 
    and d.name  = 'Apple'
    )
and exists 
    (
    select * 
    from Dependencies c 
    where b.id = c.id 
    and c.name  = 'Orange'
    );
我有两张桌子,比较简单。 第一个Employee有一个id列和一个name列 第二个表Dependencies有3列,一个id,一个eid(要链接的员工ID)和名称(apple,orange等)。

数据看起来像这样 员工表看起来像这样

id  | name
-----------
1   | Pat
2   | Tom
3   | Rob
4   | Sam

依赖关系

id  | eid | Name
--------------------
1   | 1   |  Orange
2   | 1   |  Apple
3   | 2   |  Strawberry
4   | 2   |  Apple
5   | 3   |  Orange
6   | 3   |  Banana

正如你所看到的,帕特同时拥有Orange和Apple,他需要被排除在外,而且必须通过加入,而我似乎无法让它发挥作用。最终数据应该只返回Rob

2 个答案:

答案 0 :(得分:10)

使用您想要的名称进行内连接,在您不使用的名称上左连接,然后使用where确保左连接无法匹配,如此(SQL Fiddle):

select distinct a.id, a.name
from Employee a
  inner join Dependencies b on a.id = b.eid
    and b.name = 'Orange'
  left join Dependencies c on ( a.id = c.eid
    and c.name = 'Apple')
where c.id is null;

答案 1 :(得分:0)

需要两次加入Dependencies,因为有2次测试。暂时忽略性能,您可以尝试通过命名别名来提高连接的可理解性,例如:

SELECT DISTINCT e.ID, e.Name
   FROM Employee e
   LEFT OUTER JOIN Dependencies withApple
      ON withApple.eid = e.id
      AND withApple.Name = 'Apple'
   LEFT OUTER JOIN Dependencies withOrange
      ON withOrange.eid = e.id
      AND withOrange.Name = 'Orange'
   WHERE
      withApple.id IS NULL -- Don't want this
      AND
      withOrange.id IS NOT NULL -- Do want this.

SqlFiddle