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