Разбор мини-лабы. — 9 июля 2026 г. в 16:46:00.603
Разбор мини-лабы. Подзапрос возвращает не только 1 и 2, но и NULL: 1 2 NULL Для клиента Вера условие фактически превращается в проверку: 3 NOT IN (1, 2, NULL) Интуитивно хочется прочитать это так: 3 не равен 1 и 3 не равен 2 и 3 не равен NULL Первые две части понятны: 3 <> 1 → TRUE 3 <> 2 → TRUE А третья часть не становится TRUE: 3 <> NULL → UNKNOWN В SQL NULL означает отсутствие известного значения. Поэтому обычное сравнение с NULL даёт не TRUE и не FALSE, а UNKNOWN / NULL. Итог: TRUE AND TRUE AND UNKNOWN → UNKNOWN А строка проходит через WHERE только тогда, когда условие стало TRUE. Поэтому клиенты Вера и Дмитрий не попали в результат. Как исправить? Вариант 1 — использовать NOT EXISTS: SELECT c.client_id, c.name FROM clients c WHERE NOT EXISTS ( SELECT 1 FROM orders o WHERE o.client_id = c.client_id ); Результат: 3 Вера 4 Дмитрий Вариант 2 — оставить NOT IN, но убрать NULL из подзапроса: SELECT c.client_id, c.name FROM clients c WHERE c.client_id NOT IN ( SELECT o.client_id FROM orders o WHERE o.client_id IS NOT NULL ); Результат будет тем же: 3 Вера 4 Дмитрий NOT IN не плохой сам по себе. Но если подзапрос может вернуть NULL, результат может оказаться неожиданным. Практический вывод: перед NOT IN с подзапросом проверьте, может ли правая часть вернуть NULL. Для такой задачи часто безопаснее использовать NOT EXISTS или явно отфильтровать NULL, если строки с NULL не должны участвовать в проверке. На курсах по SQL и аналитике данных такие ловушки разбираются на маленьких наборах данных: так проще увидеть, где ломается логика отчёта и почему корректный на вид запрос возвращает пустой результат.

