NULL в SQL — как проверить на пустое значение
SELECT name FROM people WHERE phone IS NULL;NULL в SQL значит «значение неизвестно» или «его нет». Проверяют его только через IS NULL и IS NOT NULL. Запись WHERE phone = NULL не выдаёт ошибки, но никогда ничего не находит.
Пример — таблица, где у Бориса телефона нет, а у Веры записана пустая строка:
CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT, phone TEXT);
INSERT INTO people (name, phone) VALUES
('Анна', '+375291112233'),
('Борис', NULL),
('Вера', '');Почему = NULL не работает
Любое сравнение с неизвестным значением даёт не «да» и не «нет», а снова неизвестное — NULL:
SELECT NULL = NULL, NULL IS NULL, 5 + NULL, NULL > 1;| NULL = NULL | NULL IS NULL | 5 + NULL | NULL > 1 |
|---|---|---|---|
| NULL | 1 | NULL | NULL |
WHERE оставляет только строки, где условие верно, а NULL — не «верно». Поэтому = NULL и <> NULL отбрасывают все строки. Даже два NULL не равны друг другу: два неизвестных значения могут быть разными.
IS NULL и IS NOT NULL
SELECT name FROM people WHERE phone IS NULL;
SELECT name FROM people WHERE phone IS NOT NULL;Первый запрос найдёт Бориса, второй — Анну и Веру: у Веры значение есть, просто пустое.
NULL и пустая строка
'' (пустая строка) — это значение: текст длиной ноль. NULL — отсутствие значения. Чтобы найти и то, и другое:
SELECT name FROM people WHERE phone IS NULL OR phone = '';Ответ — Борис и Вера. Привести пустые строки к NULL можно так: UPDATE people SET phone = NULL WHERE phone = '';.
В Oracle пустая строка и NULL — одно и то же. В SQLite, MySQL и PostgreSQL — разные значения.
Заменить NULL на значение
COALESCE возвращает первый аргумент, который не NULL:
SELECT name, COALESCE(phone, 'нет') AS phone FROM people;| name | phone |
|---|---|
| Анна | +375291112233 |
| Борис | нет |
| Вера |
COALESCE есть во всех СУБД. Короткие варианты для двух аргументов: IFNULL (SQLite, MySQL), ISNULL (SQL Server), NVL (Oracle). Обратная функция — NULLIF(phone, ''): вернёт NULL, если значение равно второму аргументу, — так пустая строка превращается в NULL прямо в запросе.
Где NULL ведёт себя неожиданно
- Арифметика и склейка.
5 + NULLи'a' || NULLдаютNULL. Сумма в строке, где одно слагаемое неизвестно, тоже неизвестна — оборачивайте столбцы вCOALESCE(столбец, 0). - Неравенство.
WHERE phone <> '+375291112233'вернёт только Веру: строка Бориса сNULLотброшена. Если она нужна —WHERE phone <> '+375291112233' OR phone IS NULL. - Итоги.
COUNT(phone),SUM,AVGпропускаютNULL;COUNT(*)считает все строки. Подробно — в справке Как посчитать строки. - Сортировка. SQLite и MySQL при
ORDER BY phoneставятNULLпервыми, PostgreSQL — последними. Явно:ORDER BY phone NULLS LAST(PostgreSQL, SQLite 3.30 и новее). - NOT IN. Если в списке есть
NULL,NOT INне находит ничего:2 NOT IN (1, NULL)— этоNULL. Подробно — в уроке Подзапросы. - UNIQUE. Строк с
NULLв уникальном столбце может быть много:NULLне равенNULL, значит, и повтора нет.
Как запретить NULL
Если значение обязательно, объявите столбец NOT NULL — тогда пустоту не пропустит сама СУБД (см. урок Создание таблицы). Добавить NOT NULL в готовую таблицу можно, только когда в столбце уже нет NULL: сначала заполните пустые места через UPDATE.