Вы ищете пользователей без заказов запросом SELECT u.user_id FROM users u WHERE u.user_id NOT IN (SELECT o.user_id FROM orders o). Почему он может вернуть 0 строк и какой подход безопаснее?

ANOT IN корректен на любых данных: разница только в скорости относительно NOT EXISTS
BNOT IN требует ORDER BY в подзапросе: без сортировки фильтр работает нестабильно и строки могут пропадать
CNULL в подзапросе делает NOT IN равным UNKNOWN для всех строк: безопаснее использовать NOT EXISTS с корреляцией
DЗамена NOT IN на <> по списку значений исключает NULL из сравнения и даёт корректный набор строк
Правильный ответ. NOT EXISTS проверяет отсутствие связанных строк, а NOT IN чувствителен к NULL в списке значений и может обнулить выборку.

Разбор

В трёхзначной логике SQL выражение x NOT IN (...) становится UNKNOWN, если в списке есть NULL, даже когда явного совпадения нет. В WHERE это означает, что строка не пройдёт фильтр, и итог может оказаться пустым. NOT EXISTS формулирует задачу иначе: «нет ни одной строки, удовлетворяющей связи и условию», и поэтому надёжнее для анти-джойна. Замены через <> или ORDER BY проблему NULL не решают.

Проверь себя · 1/3разбор после ответа
Вы считаете метрику: доля пользователей, которые совершили покупку в течение 7 дней после регистрации. Какой вариант построения запроса делает логику наиболее проверяемой и удобной для отладки?
Тренировать SQL в Telegram

Ещё вопросы по теме «Подзапросы и CTE»