2015-12-01 2 views
0

В нашей программе у нас есть отношение Many-to-Many между таблицей «Человек» и таблицей «Phonem». Это заархивировано таблицей соединений «PersonPhon».Проблема с Oracle LEFT OUTER JOIN

лицо:

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, поэтому, я думаю, у моего утверждения есть ошибка, но я не могу понять, что случилось.

Edit:

Записи:

Человек-Таблица

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) 

С учетом указанных выше данных, оператор дает:

76257713 
76257713 
76257714 

Что неожиданное поведение. Ожидается, что будет только 76257714.

Если PersonPhonem-таблица пуста, она дает:

76257713 
76257714 

Какой выглядит как ожидаемое поведение, но, кажется, вводит в заблуждение.

+0

Вы можете оставить свой набор данных и ожидаемых результатов? – SriniV

+0

Я бы тоже хотел увидеть предложение WHERE. – jarlh

+0

добавлено, где задание и информация к вопросу – Scorpio

ответ

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>>