NULL-безопасное сравнение в SQL, или как избежать ловушек
Рассказываем, как избежать неприятностей при сравнении NULL значений в SQL-запросах.
224 открытий2К показов
SQL, будучи универсальным языком для работы с данными, имеет свою специфику. Одной из таких особенностей является значение NULL, которое обозначает отсутствие данных в ячейке таблицы. Понимание того, как NULL ведет себя при сравнении, критично для написания корректных и эффективных SQL-запросов.
Особенности сравнения NULL
Ключевая особенность NULL заключается в том, что любое сравнение с ним (равно, больше, меньше и т.д.) всегда дает результат NULL. Это связано с тем, что неизвестное значение нельзя сравнить с чем-либо определенным. Например:
Такое поведение может привести к неожиданным результатам, если его не учитывать. Убедитесь в этом на сайте SQLize.online
Почему так происходит?
Представьте, что вы спрашиваете: «Неизвестное число больше пяти?». Ответ очевиден: мы не можем этого знать. Точно так же в SQL: если мы сравниваем какое-либо значение с неизвестным (NULL), то результат будет неизвестным. Так же невозможно сравнивать NULL-значения между собой. Согласитесь, вопрос о равенстве или неравенстве не известных величин не имеет смыла, и ответом на такой вопрос будет «неизвестно», или NULL (в терминах языка SQL).
В чём проблема?
Представьте задачу: в базе данных предприятия имеется таблица EMPLOYEE, одна из колонок которой — DEPARTMENT — отображает отдел, в котором трудится сотрудник. Если нужно найти всех сотрудников отдела продаж (Sales), то проблем не возникает.
Что, если нужно выполнить обратную задачу — найти всех сотрудников, кроме отдела продаж. Пустяки, скажет кто-то из вас и напишет запрос:
и будет уволен, так как в список на премию не попал генеральный директор! У него в колонке DEPARTMENT стоит значение NULL, так как он не относится ни к одному из подразделений.
Как с этим жить? Традиционные подходы к работе с NULL
До появления специализированных операторов для сравнения с NULL, разработчики использовали комбинации операторов IS NULL и IS NOT NULL для проверки значений на пустоту, а также функции вроде COALESCE для обработки таких ситуаций. Например, чтобы найти всех сотрудников, не работающих в отделе кадров:
Согласитесь, не самый понятный код.
NULL-безопасное сравнение
Для упрощения работы с NULL в разных базах данных были введены специальные операторы. Например в PostgreSQL — IS DISTINCT FROM/IS NOT DISTINCT FROM
. Он позволяет сравнивать значения, включая NULL, и возвращает TRUE, если значения различны. Таким образом решение предыдущей задачи сокращается до следующего:
Этот запрос вернет всех сотрудников, у которых отдел отличается от HR, включая тех, у кого отдел не указан (NULL).
Разработчики MySQL и MariaDB пошли дальше и вместо текста ввели короткий оператор <=>, являющийся полным аналогом рператора IS DISTINCT FROM. Таким образом, в MySQL решение будет ещё лаконичней:
В чём преимущества NULL-безопасного сравнения?
- Повышенная читаемость — запросы становятся более понятными.
- Меньше ошибок — снижается риск получения некорректных результатов.
- Универсальность — работает с любыми типами данных.
Рекомендации:
- Используйте NULL-безопасное сравнение по умолчанию.
- Будьте внимательны при использовании стандартных операторов сравнения (=, != и др.) с NULL.
- Изучите особенности работы с NULL в вашей СУБД.
Хотите углубить свои знания?
Рекомендуем платформу SQLtest.online для практических занятий и отработки навыков написания SQL-запросов.
224 открытий2К показов