Выражения и NULL: вопросы для собеседования (часть 3)

NULL в SQL ведёт себя неинтуитивно: NULL = NULL возвращает не TRUE, агрегатные функции игнорируют NULL, а CASE WHEN требует аккуратного обращения с пустыми значениями. Интервьюеры любят задачи-ловушки на тему IS NULL, COALESCE, NULLIF и трёхзначной логики. Непонимание NULL — одна из самых частых ошибок даже у опытных кандидатов.

Агрегация, GROUP BY и HAVINGДаты и времяEXPLAIN и оптимизацияJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции

Вопросы 1115 из 20

11Есть выражение для маржи: `revenue - cost`. Что получится, если `revenue` = 1000, а `cost` = `NULL`? И какой вариант устойчиво вернёт 1000 при пропуске `cost`?
AРезультат 1000; устойчивый вариант: `revenue - cost`
BРезультат `NULL`; устойчивый вариант: `revenue - COALESCE(cost, 0)`
CРезультат 0; устойчивый вариант: `COALESCE(revenue - cost, 0)`
DРезультат `NULL`; устойчивый вариант: `revenue - NULL`
Ответ: Любая арифметика с `NULL` даёт `NULL`; для подстановки используйте `COALESCE` до вычисления.

Если один из операндов в арифметике равен `NULL`, результат выражения становится `NULL`, потому что значение неизвестно. Поэтому `revenue - cost` при `cost = NULL` даст `NULL`. Чтобы трактовать пропущенную себестоимость как 0 (частая аналитическая договорённость), заменяют её заранее: `revenue - COALESCE(cost, 0)`. Это делает метрику устойчивой и предсказуемой.

12Как поведёт себя фильтр `WHERE country IN ('RU', 'KZ')` для строки, где `country` = `NULL`?
AСтрока попадёт в результат, потому что `NULL` не мешает `IN`
BСтрока попадёт в результат, если в списке есть хотя бы 2 значения
CSQL выдаст ошибку из-за `NULL`
DСтрока не попадёт в результат, потому что условие не станет `TRUE`
Ответ: При `country = NULL` выражение `country IN (...)` даёт не `TRUE`, поэтому строка не проходит `WHERE`.

`IN` — это набор сравнений на равенство. Если `country = NULL`, то сравнение с каждым элементом (`'RU'`, `'KZ'`) даёт `UNKNOWN`. В итоге всё выражение не становится `TRUE`, и строка не проходит фильтр `WHERE`. Если нужно включать `NULL`, добавляют `OR country IS NULL`.

13В таблице `users` столбец `is_test` может быть 0, 1 или `NULL`. Нужно исключить тестовых пользователей (где `is_test` = 1), но оставить остальных, включая `NULL`. Какой фильтр корректен?
A`WHERE is_test <> 1`
B`WHERE is_test = 0`
C`WHERE is_test <> 1 OR is_test IS NULL`
D`WHERE is_test != NULL`
Ответ: Условие `<>` исключает строки с `NULL`, если не добавить явную проверку.

`WHERE is_test <> 1` не пропустит строки с `is_test = NULL`, потому что сравнение даст `UNKNOWN`. Если по смыслу `NULL` означает «неизвестно/не отмечен» и таких пользователей нужно оставить, добавляют `OR is_test IS NULL`. Вариант `WHERE is_test = 0` тоже исключит `NULL`, что меняет смысл выборки.

14Нужно посчитать выручку по заказу как `price * quantity`, где `quantity` может быть `NULL` (не заполнили). По бизнес-правилу `NULL` нужно считать как 1. Какое выражение корректнее?
A`price * COALESCE(quantity, 1)`
B`COALESCE(price * quantity, 1)`
C`COALESCE(price, 1) * quantity`
D`CASE WHEN price IS NULL THEN 1 ELSE price * quantity END`
Ответ: Если `NULL` находится в одном из множителей, замените его до умножения: `COALESCE(quantity, 1)`.

При `price * quantity` и `quantity = NULL` результат будет `NULL`. Если по смыслу пропущенное количество нужно трактовать как 1, корректно заменить именно `quantity` до вычисления: `price * COALESCE(quantity, 1)`. Вариант `COALESCE(price * quantity, 1)` подменяет целый результат на 1 и нарушит логику, если `price` не `NULL`.

15В таблице `users` поле `phone` бывает `NULL` и бывает пустой строкой. Какое утверждение верное?
AПустая строка и `NULL` — одно и то же, их можно проверять только через `phone IS NULL`
B`phone = ''` найдёт и пустые строки, и `NULL`
C`phone IS NULL` найдёт только `NULL`, а `phone = ''` найдёт только пустые строки
D`phone IS NOT NULL` вернёт только строки, где `phone = ''`
Ответ: `NULL` и пустая строка — разные вещи: `IS NULL` проверяет только `NULL`, а `= ''` — только пустую строку.

`NULL` означает отсутствие/неизвестность значения, а пустая строка — это конкретное значение «строка длины 0». Условие `phone IS NULL` выберет только пропуски (`NULL`). Условие `phone = ''` выберет только пустые строки и не выберет `NULL`, потому что сравнение с `NULL` даёт `UNKNOWN`. Если нужно найти оба варианта, используют, например, `phone IS NULL OR phone = ''`.

1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать в Telegram

Другие темы: SQL

Агрегация, GROUP BY и HAVINGДаты и времяEXPLAIN и оптимизацияJOIN и операции множествОсновы SQL-запросовСтроки и приведение типовПодзапросы и CTEОконные функции