简体   繁体   中英

Trouble with Oracle LEFT OUTER JOIN

In our program, we have a Many-To-Many relation between a table 'Person' and a table 'Phonem'. This is archieved by an join table, 'PersonPhon'.

Person:

PERSID 
NAME
FIRSTNAME
DATEOFBIRTH
TYPE
[...]

PersonPhon:

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

Phonem:

PHONID
PHONEM

Due to a bug, some recent Persons were persisted without a reference to their respective Phonem entries. To read them from the database, I created a statement:

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

This statement was meant to give me all Persons with no respective entry in PersonPhon, and, with test data (only Persons without PersonPhon-entries) this works well. However, the statement also selects Persons if they have PersonPhon-entries, so I guess my statement has an error, yet I cannot figure out whats wrong.

Edit:

Entries:

Person-Table

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

PersonPhon-Table

PEPHPERSID | PEPHPHONID
76257713 | 21000
76257713 | 26000    

Phonem-Table

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

With the above data, the statement gives:

76257713 
76257713 
76257714 

Which is unexpected behaviour. Expected would be just 76257714 .

If the PersonPhonem-Table is empty, it gives:

76257713 
76257714 

Which looks like the expected behaviour, but seems to be misleading.

If you are trying to find rows in person that don't have an entry in another table, it sounds like you want a not exists rather than a left outer join . You could do a left outer join and then have a where clause that looks to see that the left joined table's values are null but that is generally less readable.

My guess is that you want

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM