Работа с NULL в SQL: как считать NULL и NOT NULL

Работа с NULL — одна из частых и запутанных задач при анализе данных и администрировании баз. Понимание того, что такое NULL и как он ведёт себя в запросах и агрегациях, позволяет получать корректные и воспроизводимые выводы из данных.
Что такое NULL в SQL
NULL — это отсутствие значения: поле оставлено пустым или значение неизвестно. NULL не равняется 0 и не равняется пустой строке ‘’ — это отдельное состояние.
Краткая дефиниция: NULL обозначает «нет значения» и подчиняется трёхзначной логике (TRUE, FALSE, UNKNOWN).
Почему это важно:
- Операторы =, <, >, <> при сравнении с NULL возвращают UNKNOWN, а не TRUE/FALSE.
- В WHERE условии UNKNOWN трактуется как FALSE — строки с NULL обычно отфильтровываются, если явно не проверять IS NULL.
Пример создания таблицы и вставки записей с NULL:
CREATE TABLE Employee (
FirstName VARCHAR(50),
LastName VARCHAR(50),
PhoneNum VARCHAR(15),
Salary FLOAT
);
INSERT INTO Employee (FirstName, LastName, PhoneNum, Salary)
VALUES
('Maxwell', 'Ayomide', '812-345-6789', 150000.00),
('David', 'Tosin', NULL, 450000.00),
('Eben', 'Teniola', '912-345-6789', 590000.00),
('Kenneth', 'Olisa', '809-456-8732', NULL),
('Esther', 'Oge', NULL, NULL);Вы можете обновлять строки с NULL через UPDATE, если условие совпадает:
UPDATE Employee
SET FirstName = 'Esther'
WHERE Salary = 200000;Проверка результата:
SELECT * FROM Employee;Когда NULL полезен
NULL полезен, когда значение неизвестно, не запрошено или неприменимо к строке. Примеры:
- Данные ещё не введены (анкета, отложенный сбор данных).
- Поле не относится к сущности (например, номер телефона для организации без телефона).
- Временное отсутствие данных при интеграции источников.
Проверка NULL и NOT NULL
IS NULL возвращает строки, где значение отсутствует:
SELECT FirstName, LastName, PhoneNum
FROM Employee
WHERE PhoneNum IS NULL;IS NOT NULL — противоположное условие, возвращает строки с наличием значения:
SELECT FirstName, LastName, PhoneNum
FROM Employee
WHERE PhoneNum IS NOT NULL;Как считать NULL в столбце
COUNT() ведёт себя по-разному в зависимости от аргумента:
- COUNT(*) считает строки (включая те, где колонка = NULL).
- COUNT(column) считает только ненулевые значения в указанной колонке.
Пример: посчитать количество NULL в PhoneNum:
SELECT COUNT(*) AS [Total Number of NULL]
FROM Employee
WHERE PhoneNum IS NULL;Посчитать количество NOT NULL в PhoneNum:
SELECT COUNT(PhoneNum) AS [Total Number of Non-NULL Values]
FROM Employee
WHERE PhoneNum IS NOT NULL;Полезный приём — вернуть оба числа в одной строке:
SELECT
SUM(CASE WHEN PhoneNum IS NULL THEN 1 ELSE 0 END) AS [Number Of Null Values],
COUNT(PhoneNum) AS [Number Of Non-Null Values]
FROM Employee;Объяснение: CASE отмечает NULL как 1, затем SUM суммирует такие метки.
Частые ошибки и когда подход проваливается
- Нельзя писать WHERE PhoneNum = NULL — такое условие всегда даёт пустой результат.
- COUNT(column) не считает NULL — новички удивляются, когда COUNT меньше ожидаемого.
- Пустая строка ‘’ и NULL — разные вещи. В текстовых полях ‘’ считается значением.
- В разных СУБД поведение функций может отличаться (например, агрегаты, индексирование NULL).
Альтернативные приёмы и полезные функции
- COALESCE(col, replacement) — заменить NULL на значение по умолчанию в выводе.
- NULLIF(expr1, expr2) — вернуть NULL, если значения равны (удобно для очистки).
- FILTER (Postgres) — альтернативный синтаксис для агрегатов: COUNT(*) FILTER (WHERE PhoneNum IS NULL).
Примеры:
SELECT COALESCE(PhoneNum, 'NO_PHONE') AS PhoneDisplay FROM Employee;
-- Postgres-specific
SELECT
COUNT(*) FILTER (WHERE PhoneNum IS NULL) AS num_null,
COUNT(*) FILTER (WHERE PhoneNum IS NOT NULL) AS num_not_null
FROM Employee;Ментальные модели и эвристики
- Думайте о NULL как о «третьем состоянии» помимо true/false или 1/0.
- Для агрегаций сначала решите: вы хотите считать строки или значения в колонке?
- Всегда явно обрабатывайте NULL на входе и выводе — это уменьшает неожиданные результаты.
Производительность и индексирование
- Индексы могут или не могут включать NULL-значения в зависимости от СУБД и типа индекса.
- WHERE PhoneNum IS NULL по большим таблицам может быть дорогостоящей операцией без подходящего покрытия.
- Рассмотрите хранение флага (has_phone BOOL) если часто фильтруете по наличию значения.
Важно: перед модификацией структуры таблицы (добавление NOT NULL, замена NULL на дефолт) проверьте влияние на приложение и интеграции.
Проверки, тесты и критерии приёмки
Критерии приёмки:
- Запросы возвращают корректное количество NULL и NOT NULL для тестового набора данных.
- Замена NULL на дефолт не изменила смысл данных для потребителей.
- Производительность запросов соответствует SLO/ожиданиям (время выполнения приемлемо).
Тестовые случаи:
- Таблица с 0 NULL, 50% NULL, 100% NULL.
- Смешанные ‘’ и NULL в текстовых колонках.
- JOIN, где ключи могут быть NULL — проверьте поведение LEFT/INNER JOIN.
Чек-листы для ролей
Аналитик:
- Проверить, что NULL интерпретируются правильно в анализе.
- Использовать COALESCE при необходимости представить данные для отчёта.
Разработчик:
- Не полагаться на сравнение = NULL.
- Добавить документацию по смыслу NULL в схеме.
DBA:
- Оценить индексацию и влияние NULL на планы выполнения.
- Решить правила NULL/NOT NULL для новых колонок.
Быстрый чек-лист и сниппет (cheat sheet)
- Посчитать NULL: SELECT COUNT(*) FROM t WHERE col IS NULL;
- Посчитать NOT NULL: SELECT COUNT(col) FROM t;
- Оба сразу: SELECT SUM(CASE WHEN col IS NULL THEN 1 ELSE 0 END), COUNT(col) FROM t;
- Показать замену: SELECT COALESCE(col, ‘—‘) FROM t;
Резюме
NULL — это не баг, а состояние данных. Осознанное обращение с NULL (IS NULL/IS NOT NULL, COUNT(), COALESCE, CASE) делает анализ корректным и предсказуемым. Проверьте поведение в вашей СУБД, добавьте тесты и документируйте смысл NULL в каждой колонке.
Важно: отличайте NULL от пустой строки и проверяйте влияние на производительность при больших объёмах данных.
Ключевые команды и идеи собраны в этом материале — используйте их как SOP перед запуском отчётов или изменением схемы.
Похожие материалы
Calendly: как работает и как настроить
Связать Amazon Echo с Google Календарём
Настройка уведомлений Google Calendar
Синхронизация Google-календаря с Календарём Windows 10
Как использовать Google Calendar по‑максимуму