Oracle LEFT OUTER JOIN的麻烦

时间:2015-12-01 07:32:57

标签: sql oracle11g

在我们的程序中,表'Person'和表'Phonem'之间存在多对多关系。这是由一个连接表'PersonPhon'来实现的。

人:

PERSID 
NAME
FIRSTNAME
DATEOFBIRTH
TYPE
[...]

PersonPhon:

PEPHPERSID <-- references the person
PEPHPHONID <-- references the phonem

Phonem:

PHONID
PHONEM

由于存在错误,一些最近的人员在没有参考其各自的Phonem条目的情况下被持久化。为了从数据库中读取它们,我创建了一个声明:

select p.persid from    
Person p left outer join PersonPhon ph 
on p.persid = ph.pephpersid              
where p.type = 'natural'

这个声明是为了让我所有在PersonPhon中没有相应条目的人,并且,对于测试数据(只有没有PersonPhon条目的人),这个效果很好。但是,如果他们有PersonPhon条目,语句也会选择Persons,所以我猜我的语句有错误,但我无法弄清楚什么是错的。

编辑:

条目:

与人表

PERSID | NAME | FIRSTNAME | AGE | TYPE (other columns ommitted)
76257713 | Wilko | Roger| 30 | natural
76257714 | Martian | Marvin | 50 | natural

PersonPhon-表

PEPHPERSID | PEPHPHONID
76257713 | 21000
76257713 | 26000    

Phonem-表

PHONID | PHONEM
21000 | 4875122
26000 | 7468112
most entries omitted (> 100000)

根据以上数据,该陈述给出:

76257713 
76257713 
76257714 

意外行为。预计只有76257714

如果PersonPhonem-Table为空,则显示:

76257713 
76257714 

看起来与预期行为一样,但似乎有误导性。

1 个答案:

答案 0 :(得分:2)

如果您要在person中找到在另一个表格中没有条目的行,则听起来您需要not exists而不是left outer join。您可以执行left outer join,然后使用where子句查看左侧连接表的值是null,但通常不太可读。

我猜你想要

SELECT *
  FROM person p
 WHERE NOT EXISTS( SELECT 1
                     FROM PersonPhon ph
                    WHERE p.persid = ph.pephpersid )
   AND <<your additional predicates>>