Примечание: поскольку кто-то утверждал, что внешняя ссылка мертва в ответе Сушанта Бутты, я разместил этот контент здесь как отдельный ответ.
Остерегайтесь NULLS .
Сегодня я столкнулся с очень странным поведением запроса при использовании IN и NOT INоператоров. На самом деле я хотел сравнить две таблицы и выяснить , является ли значение из table bсуществовавших в table aили нет , и выяснить его поведение , если столбец содержитnull значение. Поэтому я просто создал среду для проверки этого поведения.
Создадим стол table_a.
SQL> create table table_a ( a number);
Table created.
Создадим стол table_b.
SQL> create table table_b ( b number);
Table created.
Вставьте некоторые значения в table_a.
SQL> insert into table_a values (1);
1 row created.
SQL> insert into table_a values (2);
1 row created.
SQL> insert into table_a values (3);
1 row created.
Вставьте некоторые значения в table_b.
SQL> insert into table_b values(4);
1 row created.
SQL> insert into table_b values(3);
1 row created.
Теперь мы выполним запрос, чтобы проверить наличие значения в table_a, проверив его значение с table_bпомощью INоператора using .
SQL> select * from table_a where a in (select * from table_b);
A
3
Выполните запрос ниже, чтобы проверить его отсутствие.
SQL> select * from table_a where a not in (select * from table_b);
A
1
2
Результат пришел как и ожидалось. Теперь мы вставим nullзначение в таблицу table_bи посмотрим, как ведут себя два вышеуказанных запроса.
SQL> insert into table_b values(null);
1 row created.
SQL> select * from table_a where a in (select * from table_b);
A
3
SQL> select * from table_a where a not in (select * from table_b);
no rows selected
Первый запрос вел себя так, как ожидалось, но что случилось со вторым запросом? Почему мы не получили никакого вывода, что должно было произойти? Есть ли разница в запросе? Нет .
Изменение есть в данных таблицы table_b. Мы ввели nullзначение в таблицу. Но почему он так себя ведет? Давайте разделим два запроса в "AND"и "OR"оператор.
Первый запрос:
Первый запрос будет обрабатываться внутри примерно так. Таким образом, a nullне создаст здесь проблемы, поскольку мои первые два операнда будут либо оценивать, trueлибо false. Но мой третий операнд не a = nullбудет ни оценивать trueни false. Будет оценивать nullтолько.
select * from table_a whara a = 3 or a = 4 or a = null;
a = 3 is either true or false
a = 4 is either true or false
a = null is null
Второй запрос:
Второй запрос будет обработан, как показано ниже. Поскольку мы используем "AND"оператор, и что-либо, кроме trueлюбого операнда, не даст мне никакого вывода.
select * from table_a whara a <> 3 and a <> 4 and a <> null;
a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null
Так как же нам с этим справиться? Мы выберем все not nullзначения из таблицы table_bпри использовании NOT INоператора.
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
1
2
Поэтому всегда будьте осторожны со NULLзначениями в столбце при использовании NOT INоператора.
Остерегайтесь NULL !!
inЗаявление будет разобрано идентичноfield=val1 or field=val2 or field=val3. Ввод ноля там будет сводиться к тому,field=nullчто не сработает.