Подзапросы

NULL значения в NOT IN

NOT IN - опасная штука. Нужно гарантировать, что в результате подзапроса не встретится значение NULL.

Запрос

SELECT *
  FROM store
 WHERE store_id NOT IN (100, 300, 500)
 ORDER BY store_id

вернет все магазины, кроме магазинов с идентификаторами 100, 300 и 500.

#store_idnamesite_url
1200Марсmars.ru
2201Сатурнsaturn.ru
3301Адалин-familyadalin-ultra.ru
4302Адалин-ultra
5400Европаevropa.ru
6600Umi
7800Универсам
8900Bigbig.ru

Запрос

SELECT *
  FROM store
 WHERE store_id NOT IN (100, 300, 500, NULL)
 ORDER BY store_id

не вернет ничего.

Почему так? store_id NOT IN (100, 300, 500, NULL) принимает значение TRUE, когда store_id не равно ни одному из значений в скобках. Это условие эквивалентно

 WHERE store_id != 100
   AND store_id != 300
   AND store_id != 500
   AND store_id != NULL

Выражение store_id != NULL принимает значение NULL, что означает - неизвестно. Так как неизвестно равно ли store_id одному из значений, то строка отбрасывается.

В список NOT IN значение NULL обычно не пишут. На этот подводный камень часто натыкаются при использовании подзапросов.

Получим список сотрудников, которые не сделали ни одной продажи:

SELECT e.employee_id,
       e.last_name,
       e.first_name
  FROM employee e
 WHERE e.employee_id NOT IN (SELECT p.employee_id
                               FROM purchase p)
0 строк

Исключим из подзапроса NULL значения:

SELECT e.employee_id,
       e.last_name,
       e.first_name
  FROM employee e
 WHERE e.employee_id NOT IN (SELECT p.employee_id
                               FROM purchase p
                              WHERE p.employee_id IS NOT NULL)
#employee_idlast_namefirst_name
11ИвановАлексей
22МаккормикКенни
33МатвееваАнна
44ШмидтРоман
............

P.S. В SQL значение NULL может означать, что значение либо неизвестно, либо значения не существует.

Если NULL используется для роста человека, это значит, что мы пока не знаем, какой у этого человека рост.

Если NULL используется для обозначения объема бензобака автомобиля, то для электрокаров это означает, что значения не существует.

В некоторых языках программирования помимо NULL есть значение UNDEFINED.

ПредыдущаяСледующая