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

AВсе три подхода всегда возвращают одинаковый результат независимо от значений NULL в данных таблиц
BТолько LEFT JOIN ... IS NULL корректно обработает NULL, а NOT EXISTS и NOT IN дадут синтаксическую ошибку
CNOT IN вернёт пустой результат, если в столбце orders.user_id встречается хотя бы один NULL
DТолько NOT EXISTS вернёт пустой результат, если в столбце orders.user_id встречается хотя бы один NULL
Правильный ответ. Если в подзапросе встречается NULL, выражение NOT IN вернёт пустой набор, потому что сравнение с 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разбор после ответа
Два запроса: SELECT * FROM orders JOIN users ON orders.user_id = users.user_id и SELECT * FROM orders JOIN users USING(user_id). В чём ключевое ограничение USING?
Тренировать SQL в Telegram

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