Три способа найти пользователей без заказов: LEFT JOIN + IS NULL, NOT EXISTS, NOT IN. Столбец orders.user_id содержит NULL-значения. Какой подход даст неожиданный результат?

AВсе три подхода всегда возвращают одинаковый результат независимо от данных в таблицах
BТолько LEFT JOIN + IS NULL корректно обработает NULL — остальные два способа дадут ошибку
CNOT IN вернёт пустой результат, если в orders.user_id есть хотя бы один NULL
DТолько NOT EXISTS вернёт пустой результат при наличии NULL в orders.user_id
Правильный ответ. NOT IN при наличии NULL в подзапросе вернёт пустой набор, потому что сравнение с NULL даёт UNKNOWN, и ни одна строка не проходит фильтр.

Разбор

Выражение x NOT IN (1, 2, NULL) раскрывается в x<>1 AND x<>2 AND x<>NULL. Последнее сравнение всегда даёт UNKNOWN, а TRUE AND UNKNOWN = UNKNOWN — ни одна строка не пройдёт. NOT EXISTS и LEFT JOIN + IS NULL не страдают от этой проблемы: они проверяют наличие строки, а не равенство значений. Рекомендация: для анти-соединений избегать NOT IN, если в подзапросе возможны NULL.

Проверь себя · 1/3разбор после ответа
Нужно вывести пользователей, у которых есть хотя бы один заказ. У каждого пользователя может быть много заказов. Какой способ не создаст дублирование строк?
Тренировать SQL в Telegram

Ещё вопросы по теме «JOIN и операции множеств»