Всем отличного начала нового года! Вчера утром в своём Телеграм-канале опубликовал интересную задачу по SQL с собеседования про IN и NOT IN.
С первого взгляда кажущееся правильным решение на самом деле ложно. Чтобы верно ответить в задаче, нужно знать как СУБД обрабатывает элементы множества, указанные для оператора IN / NOT IN в запросе.
Вначале вот текст самой задачи. Ниже я поясню правильное решение:
В таблице CLIENTS пять строк. В первых двух строках в поле CLIENT_TYPE значение 1, ещё в двух строках в CLIENT_TYPE значение 2 и в последней строке поле CLIENT_TYPE не заполнено, то есть в последней строке в поле CLIENT_TYPE значение NULL.
Есть два запроса:
1)
SELECT * FROM CLIENTS WHERE CLIENT_TYPE IN (1)
2)
SELECT * FROM CLIENTS WHERE CLIENT_TYPE NOT IN (2, NULL)
Результирующие наборы данных, полученные в результате выполнения этих запросов, будут одинаковыми или разными?
Здесь поставь чтение на паузу и ответь на вопрос самостоятельно.
На сегодня на канале следующий разброс ответов:
Первый запрос отбирает клиентов, у которых в столбце тип указано значение 1. В результате будут отобраны две строки. Здесь все понятно. Так как в таблице клиентов ещё остаются строки, не попавшие в выбор первого запроса, со значениями в столбце тип 2 и NULL, то видится, что второй запрос должен как раз вернуть такой же результирующий набор данных. Однако, тут дело в коварном NULL в значениях для оператора NOT IN. СУБД представляет оператор NOT IN:
SELECT * FROM CLIENTS WHERE CLIENT_TYPE NOT IN (2, NULL)
в результате должны быть отобраны клиенты, у которых значение в столбце тип не равно каждому из перечисленных во множестве значений:
SELECT * FROM CLIENTS WHERE ( (CLIENT_TYPE <> 2) AND (CLIENT_TYPE <> NULL) )
С NULL не допустимо использовать операторы сравнения. При сравнении с NULL (= NULL, <> NULL) результат будет всегда отрицательным.
Второй запрос не вернёт ни одной строки данных.
Ещё больше полезного и интересного в моём Телеграмм-Канале.