2012-05-02 157 views
1

假设我有3个表:
没有releations选择记录

People 
------------- 
PID | NAME 
------------- 
1  Bob 
2  Garry 
3  Alex 
4  Peter 
5  Victor 

Tasks 
------------- 
TID | TASK 
------------- 
1  Work 
2  Work Hard 
3  Work Harder 

这任务分配到人

Assigns 
------------- 
PID | TID 
------------- 
1  2 
2  1 
4  3 

问题: 如何选择谁没有分配给任何人任务?

回答

5

LEFT JOIN方法将工作,但这里有两个,你可能会发现更容易的方法来阅读:

1.不要在

SELECT NAME 
FROM People 
WHERE PID NOT IN 
(
    SELECT PID 
    FROM Assigns 
) 

2. NOT EXISTS

SELECT NAME 
FROM People 
WHERE NOT EXISTS 
(
    SELECT * 
    FROM Assigns 
    WHERE People.PID = Assigns.PID 
) 

结果

Alex 
Victor 

相关

+0

你对** LEFT JOIN是NULL **方法有什么感想? –

+0

工程就好了谢谢! –

+0

是的,@Sergej波波夫,这应该很好,但表现可能是一个问题。 –

2

使用NOT IN子查询可以是一个更难的性能损失比左JOIN和NULL

SELECT NAME 
    FROM People 
     LEFT JOIN Assigns 
     on People.PID = Assigns.PID 
    where 
     Assigns.PID IS NULL 

期望通过使用LEFT-JOIN方法,th e People表正在通过ONCE进行连接,第二次基于索引查找。它实际上并没有查询整个第二个“Assigns”文件,以查找所有可能性然后加入(而不一定要利用索引)。左连接直接使用索引并找到一条记录,否则不会。如果没有,则PID将为NULL,从而表明在分配表中找不到该人员。

+2

如果Oracle为NOT IN解决方案和LEFT JOIN解决方案选择相同的执行计划,我不会感到惊讶 –