Коварство NOT IN в SQL (следите за NULL!)

Некоторые вещи в SQL совсем не интуитивны. Я уже писал про пагубность сравнения с NULL в SQL, но недавно снова наступил на эти грабли. Иногда в сложных запросах не всегда очевидна природа данных. Скажем, есть у вас некая таблица customers:

id key
1 25
2 26
3 NULL

Вы привыкли и ожидаете видеть, что key присутствует в таблице всегда, хотя NULL и допустим в архитектуре таблицы, но опыт и интуиция вам подсказывают неверное допущение (не доверяйте интуиции!). И вот вы пишете такого рода запрос:

SELECT *
FROM some_table
WHERE some_table.key NOT IN (
  SELECT key
  FROM customers
);

То есть фактически вы хотите видеть все записи в some_table, у которых в поле key есть значение, которого нет в таблице customers.

И вот ведь сюрприз! Какие бы данные ни содержала в себе таблица some_table, результат этого запроса всегда будет нулевой — ни одной строки он не вернет. Почему так? Да потому что в customers есть запись с id=3, у которой key — это NULL. А мы помним, что с NULL сравнивать нельзя. В общем, надо подстраховываться на такой случай. Если столбец объявлен, как NULLABLE, то в подзапросах, которые будут использоваться с NOT IN, надо явно указывать

WHERE key IS NOT NULL

 

 

6 комментариев

  1. Подскажите, пожалуйста, если я использую функцию not in, пустых полей нет, однако мне все равно выдаёт результат, где 1 из значений одной таблицы есть в другой. Каковы могут быть причины?

    1. ну вы напишете запрос сам, так трудно сказать, не видя его. Запрос и что ожидается в выборке увидеть

  2. Ну не знаю, пример спорный, допустить null в ключах и самому от этого пострадать =)

    1. наверное, стоило по-другому назвать это поле в примере, действительно

      1. Подскажите, пожалуйста, если я использую функцию not in, пустых полей нет, однако мне все равно выдаёт результат, где 1 из значений одной таблицы есть в другой. Каковы могут быть причины?

Добавить комментарий для jarique Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.