Программирование SQLDML и запросыРазработчик серверной части

При вычислении арифметического выражения один из операндов равен NULL. Какое значение получится?

При вычислении арифметического выражения один из операндов равен NULL. Какое значение получится?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Результатом арифметического выражения с операндом NULL обычно будет NULL. Это означает, что значение неизвестно или отсутствует: SQL не может достоверно вычислить результат операции. Если такое выражение используется в условии WHERE, сравнение обычно даст UNKNOWN, поэтому строка не попадёт в результат.

Исторический контекст

NULL нужен для представления отсутствующего или неизвестного значения, которое нельзя корректно заменить обычным числом, пустой строкой или нулём. Поэтому SQL использует не только TRUE и FALSE, но и третье логическое состояние — UNKNOWN.

Такой подход предотвращает подмену неизвестных данных фиктивными значениями. Например, неизвестную цену нельзя автоматически считать равной нулю: это изменило бы смысл вычислений и отчётов.

Постановка проблемы

Допустим, количество товара известно, но его цена не заполнена. Выражение количества и цены формально записывается корректно, однако итоговая сумма неизвестна.

Ошибочная замена NULL на ноль может привести к занижению выручки. Если же оставить NULL, нужно учитывать, что фильтры, сортировка и агрегатные функции могут обрабатывать такие результаты иначе, чем обычные числа.

Подробное решение

Арифметические операции обычно распространяют NULL: если неизвестен хотя бы один операнд, неизвестен и результат. Например, результатом сложения, умножения или деления с NULL будет NULL.

SELECT 10 + NULL AS addition, 10 * NULL AS multiplication, NULL / 2 AS division;

Во всех трёх выражениях результатом будет NULL. При выводе клиент может отображать его как пустое поле, но это не пустая строка и не числовой ноль.

В условии WHERE ситуация важнее: выражение с NULL часто даёт UNKNOWN. WHERE оставляет только строки, для которых условие равно TRUE; значения FALSE и UNKNOWN отбрасываются.

Если бизнес-логика требует считать отсутствующее значение нулём, это нужно указать явно, например через COALESCE. Однако такое решение допустимо только если ноль действительно имеет нужный смысл, а не просто маскирует неполные данные.

Есть важное отличие от агрегатов: многие агрегатные функции игнорируют NULL, тогда как арифметическое выражение для конкретной строки обычно возвращает NULL. Поэтому сумма отдельных выражений и выражение суммы исходных столбцов могут иметь разную семантику.

Ситуация из практики

В отчёте о заказах рассчитывалась стоимость позиции. Для части строк цена ещё не была загружена, и итоговая сумма становилась NULL. Это позволяло заметить неполные данные, но усложняло отчётность.

Рассматривались два варианта. Подстановка нуля делала отчёт числовым, но занижала общую сумму и смешивала «бесплатный товар» с «неизвестной ценой». Фильтрация таких строк скрывала проблему и уменьшала количество заказов в отчёте.

Выбрали сохранение NULL в детальном отчёте и отдельный статус неполноты данных. Для финансового итогового отчёта строки с неизвестной ценой не включали в подтверждённую выручку, а количество таких строк показывали отдельно. Это сохранило корректную семантику и сделало качество данных видимым.

Что кандидаты часто упускают

  1. Всегда ли NULL в условии означает FALSE?

Нет. Результатом может быть UNKNOWN, а не FALSE. В WHERE оба состояния не проходят фильтр, но логически это разные результаты: FALSE означает, что условие опровергнуто, а UNKNOWN — что его нельзя определить из-за отсутствующего значения.

  1. Что произойдёт при сортировке выражения, которое иногда равно NULL?

Строки с NULL будут участвовать в сортировке, но их положение зависит от правил конкретной СУБД и явно заданного направления сортировки. Поэтому для переносимого и однозначного порядка нужно явно управлять размещением NULL, если это поддерживается выбранной СУБД, либо использовать выражение, задающее требуемый приоритет.

  1. Почему агрегатная сумма может отличаться от суммы построчных выражений?

Агрегатные функции вроде SUM обычно игнорируют NULL, а арифметическое выражение с NULL для отдельной строки даёт NULL. Поэтому сумма исходных числовых столбцов может учитывать известные значения, тогда как сумма заранее вычисленных построчных результатов может зависеть от того, как именно обработаны NULL и пустой набор строк. Семантику нужно выбирать явно, особенно для финансовых расчётов.