Использование предикатов NOT в SQL - PullRequest
5 голосов
/ 18 ноября 2010

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

Я не понимаю, почему Query II и III не возвращают одинаковые результаты.Я ожидаю, что запрос II будет возвращать все строки, не выбранные Query I.

Я бы ожидал, что Query II и III дадут одинаковые результаты.На мой взгляд, результаты III правильные.

Я уверен, что что-то упустил, я просто не знаю, что.

Пример:

Таблица:

CREATE TABLE [dbo].[TestTable](
 [TestTableId] [int] NOT NULL,
    [ValueA] [int] NULL,
 [ValueB] [int] NULL
) ON [PRIMARY]

Данные:

TestTableId ValueA ValueB
1        10      5
2        20      5
3        10      NULL
4        20        NULL
5        NULL      10
6        10        10
7        NULL      NULL

Запросы:

Все записи: выберите * из TestTable

I.Запрос выбора:

select * from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5

Результат:

TestTableId ValueA ValueB
1           10   5
2           20   5

II.Тот же запрос, но НЕ

select * from TestTable 
where NOT ((ValueA = 10 or ValueA = 20) AND ValueB = 5)

Результат:

TestTableId ValueA ValueB
5           NULL   10
6           10   NULL

III.Тот же запрос, что и второй (я бы подумал)

select * from TestTable where TestTable.TestTableId not in 
    (select TestTableId from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5)

Результат:

TestTableId ValueA ValueB
3           10   NULL
4           20   NULL
5           NULL   10
6           10   10
7           NULL   NULL

Ответы [ 2 ]

5 голосов
/ 18 ноября 2010

NULL - забавные существа.Они ответят «Я не знаю» на оба следующих вопроса:

Are you 5?  (... WHERE ValueB = 5)

и

Are you Not 5? (... WHERE NOT ValueB = 5)

В результате значения NULL будут исключены из обоих запросы, как вы нашли.

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

... WHERE (ValueB IS NULL OR NOT ValueB = 5) ...
2 голосов
/ 18 ноября 2010

При использовании NOT значения NULL представляют собой особую ситуацию.

A NULL - это значение unknown . SQL не может сказать, является ли он NOT a 12, но он может сказать, является ли он a 12.

Хороший пример:

Вы на вечеринке. Вы знаете 2 из 12 имен людей в комнате, обоих зовут Джон. Вы можете сказать мне, кто такие "Джон". Вы не можете сказать мне, кто такой "Не Джек", кроме двух "Джонов". Что касается SQL, остальные 10 человек в комнате имеют имя NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...