NULL
Работа с неопределенными значениями
Теория
Вот мы и добрались до NULL, одной из любимых тем пользователей, особенно тех, кто проводит с нами технические собеседования. NULL - это неопределенное значение, так его правильно называть. В SQL это означает не ноль и не пустую строку, а именно неопределенное значение. Вы можете думать об этом как: значение в поле сейчас неизвестно, ещё не заполнено или для этой строки его просто нет.
Например:
• у работника зарплата пока не внесена в систему;
• у заказа ещё нет даты отгрузки;
• в анкете человек не указал телефон.
Во всех этих случаях в базе данных в конкретных столбцах, где еще нет информации, может стоять NULL. Это не ошибка и не специальный текст. Это отдельное неопределенное состояние данных.
Важно: из-за этого с NULL нельзя обращаться как с обычным значением. Его нельзя корректно искать через обычные операторы сравнения, изученные в прошлых темах: = NULL или != NULL. Для проверки существуют специальные конструкции IS NULL и IS NOT NULL.
Например:
• у работника зарплата пока не внесена в систему;
• у заказа ещё нет даты отгрузки;
• в анкете человек не указал телефон.
Во всех этих случаях в базе данных в конкретных столбцах, где еще нет информации, может стоять NULL. Это не ошибка и не специальный текст. Это отдельное неопределенное состояние данных.
Важно: из-за этого с NULL нельзя обращаться как с обычным значением. Его нельзя корректно искать через обычные операторы сравнения, изученные в прошлых темах: = NULL или != NULL. Для проверки существуют специальные конструкции IS NULL и IS NOT NULL.
Синтаксис
SELECT column1, -- указываем столбцы, которые хотим получить
column2
FROM table_name -- указываем таблицу, из которой берём данные
WHERE column1 IS NULL; -- оставляем строки, где в column1 нет значения
SELECT column1,
column2
FROM table_name
WHERE column1 IS NOT NULL; -- оставляем строки, где в column1 есть значение
SQL
IS NULL ищет строки, где значение отсутствует. А что значит значение отсутствует? Это значит, что вместо какого-то существующего (определенного) значения там установлен NULL. IS NOT NULL — наоборот, оставляет только строки с заполненным значением.
Еще раз: записи = NULL и != NULL работать не будут. SQL не считает NULL обычным значением для сравнения, поэтому для него нужны отдельные операторы.
Резюме: нельзя сравнивать определенное значение с неопределенным используя обычные операторы сравнения.
Важно: NULL и '' — не одно и то же. Пустая строка — это значение, просто пустое. NULL — это отсутствие значения вообще.
Еще раз: записи = NULL и != NULL работать не будут. SQL не считает NULL обычным значением для сравнения, поэтому для него нужны отдельные операторы.
Резюме: нельзя сравнивать определенное значение с неопределенным используя обычные операторы сравнения.
Важно: NULL и '' — не одно и то же. Пустая строка — это значение, просто пустое. NULL — это отсутствие значения вообще.
Примеры
1. Находим пользователей, у которых не указан город
Этот запрос покажет только тех пользователей, у которых значение в столбце city отсутствует. То есть город не просто пустой, а именно NULL.
🔄 Попробуйте изменить запрос:
- • Поменяйте IS NULL на IS NOT NULL
- • Добавьте сортировку по имени: ORDER BY first_name ASC
2. Показываем 3 последних заказа, у которых не указан статус
Здесь NULL показывает, что статус заказа пока не определён. Сначала WHERE оставляет только такие заказы, затем ORDER BY сортирует более поздние заказы в начало таблицы, а LIMIT 3 оставляет только три строки.
🔄 Попробуйте изменить запрос:
- • Поменяйте условие на status IS NOT NULL
- • Уберите LIMIT 3 и посмотрите все заказы без статуса
3. Оставляем только товары, у которых категория заполнена
Это обратная проверка на NULL. Запрос уберёт товары без категории и оставит только те, где категория уже указана.
🔄 Попробуйте изменить запрос:
- • Поменяйте условие на category IS NULL и посмотрите только товары без категории
- • Добавьте сортировку по цене: ORDER BY price DESC
4. Смотрим, почему = NULL не работает
Этот запрос написан правильно и покажет пользователей без города. Но будет полезно специально показать маленький эксперимент. NULL не ведёт себя как обычное значение, поэтому запись через = NULL здесь не найдёт нужные строки.
🔄 Попробуйте изменить запрос:
- • Замените IS NULL на = NULL и посмотрите, что результат станет пустым
- • После этого верните правильную запись IS NULL и сравните результат ещё раз
Типичные ошибки
Пишут = NULL вместо IS NULL
Запрос вида WHERE salary = NULL не найдёт нужные строки. Для проверки на отсутствие значения нужно писать WHERE salary IS NULL.
Пишут != NULL вместо IS NOT NULL
Чтобы оставить только заполненные значения, нужен оператор IS NOT NULL. Сравнение через != NULL для этого не подходит.
Путают NULL и пустую строку
'' — это значение, хоть и пустое. NULL — это отсутствие значения. Поэтому проверка WHERE column IS NULL не найдёт строки, где в колонке лежит ''.
Считают, что NULL — это то же самое, что 0
Ноль — это обычное числовое значение. NULL — это информация о том, что значения нет. У этих двух состояний разный смысл, и их нельзя смешивать.
Забывают, что NULL по-особому ведёт себя в сортировке
В PostgreSQL положение NULL зависит от направления сортировки. При ORDER BY salary ASC пустые значения окажутся в конце, а при ORDER BY salary DESC — в начале. Если порядок важен, задавайте его явно через NULLS FIRST или NULLS LAST. Вспомним, почему так: потому что для PostgreSQL NULL является наибольшим значением из всех известных (определенных).
Практика
Проверь себя
Ответьте на вопросы, чтобы закрепить материал:
1
Что означает NULL в SQL?
2
Чем NULL отличается от пустой строки ''?
3
Какой фрагмент запроса правильно проверяет, что город у пользователя не указан?
4
Что произойдёт, если написать WHERE category = NULL?
5
Что вернёт выражение NULL = NULL?
6
Что вернёт запрос SELECT 5 + NULL;?
7
Напишите запрос к таблице workers, который выведет worker_id, first_name, salary и hire_date только для работников, у которых зарплата пока не указана. Более поздние даты найма должны идти выше.
8
Где по умолчанию окажутся строки с NULL в запросе ORDER BY city ASC, если не писать NULLS FIRST или NULLS LAST?