Примечание: поскольку кто-то утверждал, что внешняя ссылка мертва в ответе Сушанта Бутты, я разместил этот контент здесь как отдельный ответ.
Остерегайтесь 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
что не сработает.