2010-01-23 3 views
18

Я не уверен, допустил ли я ошибку в логике.внутреннее соединение по нулевому значению

Если у меня есть запрос, и я делаю внутреннее соединение с нулевым значением, я всегда получаю никаких результатов или проигнорирует соединение и преуспеет? пример

user { id PK, name NVARCHAR NOT NULL, banStatus nullable reference } 

если я пишу и u.banStatus, я не получу строк?

select * from user as u 
join banstatus as b on u.banStatus=b.id 
where id=1 
+0

Почему бы просто не попробовать? –

+1

NULL не определено, поэтому, если у нас есть NULL = NULL, тогда результат всегда будет ложным, так как мы сравниваем два неопределенных значения. Надеюсь, он ответит на ваш вопрос. –

+0

В вашем запросе также есть ошибка. Поле 'id' в вашем аргументе where неоднозначно - это может быть' u.id' или 'b.id'. –

ответ

6

Когда вы делаете INNER JOIN, NULL значения не совпадают ни с чем. Даже не друг с другом. Вот почему ваш запрос не возвращает никаких строк. (Source))

44

Вы не получите строку, если объединение является нулевым, поскольку NULL не может быть равно ни одному, даже NULL.

Если вы измените его на LEFT JOIN, вы получите строку.

С внутреннее соединение:

select * from user as u 
join banstatus as b on u.banStatus=b.id 

1, '1', 1, 'Banned' 

С левой присоединиться:

select * from user as u 
left join banstatus as b on u.banStatus=b.id 

1, '1', 1, 'Banned' 
2, 'NULL', , '' 

Используя этот тест данные:

CREATE TABLE user (id int, banstatus nvarchar(100)); 
INSERT INTO user (id, banstatus) VALUES 
(1, '1'), 
(2, 'NULL'); 

CREATE TABLE banstatus (id int, text nvarchar(100)); 
INSERT INTO banstatus (id, text) VALUES 
(1, 'Banned'); 
+2

, мне не нужны тестовые данные или что-то другое, кроме конформации (да, вы не получите строк), но хорошо для будущих читателей. + 1 и принять. – 2010-01-23 12:09:38

5

Это внутренние соединения на нулям (синтаксис Oracle):

select * 
    from user 
     uu 
    join banstatus 
     bb 
    on uu.banstatus = bb.id 
     or 
     uu.banstatus is null and bb.id is null 
+0

, так что это соединение, когда пользователь и bb равны нулю? интересно. id никогда не будет null или 0. Если я написал 'on uu.banstatus = bb.id или uu.banstatus null, он будет игнорировать его и присоединиться и не дать мне 0 строк? это будет то же самое, что и левое соединение? Интересно. Я больше не нуждаюсь в ответе, но если вам хочется дать то, что я прочитаю. – 2010-01-24 06:42:55

+1

Нет, это не будет вести себя как левое соединение. Если 'bb.id' никогда не является нулевым, в результате не будет никаких строк с нулевым' uu.banstatus'. –

+0

+1. Интересное сообщение: D – 2010-01-25 00:20:57