TGViewer
SQL: Реляционные базы данных SQL: Реляционные базы данных @relational_databases · 986 subscribers
Post #132 1.81K
0️⃣ NULL в SQL - не "ничего", а "неизвестно"

Когда вы видите NULL в таблице, интуиция подсказывает: "Это просто пусто. Ничего нет. Поле не заполнено".
Но реляционная модель намеренно отказывается от такого упрощения. Вместо "ничего" она вводит состояние неопределённости: значение существует, но нам о нём ничего не известно. Именно поэтому NULL - это не данные, а метаинформация о недостатке данных.

И эта тонкость ломает привычную булеву логику, заставляя SQL работать с трёхзначной логикой (3VL):

➖ TRUE - утверждение верно,
➖ FALSE - утверждение ложно,
➖ UNKNOWN - мы не можем судить

0️⃣ Почему age = NULL ничего не возвращает?

Рассмотрим запрос:
SELECT name FROM employees WHERE age = NULL;

Логика кажется простой: "выведи всех, у кого возраст не указан"

Но СУБД думает иначе. Выражение вида age = NULL не возвращает ни TRUE, ни FALSE.
Поскольку NULL обозначает отсутствие известного значения, сравнение любого выражения с NULL с использованием стандартных операторов (=, <>, <, >, и т.д.) всегда приводит к логическому значению UNKNOWN.

Согласно семантике WHERE, в результирующий набор включаются только те строки, для которых условие оценивается как TRUE. Значения FALSE и UNKNOWN в этом контексте ведут себя одинаково - соответствующие строки исключаются из вывода.

Следовательно, конструкция из примера никогда не возвращает строк, даже если в столбце age присутствуют значения NULL.

Правильный синтаксис - специальный оператор:
SELECT name FROM employees WHERE age IS NULL; -- также антипод IS NOT NULL

Здесь вы не сравниваете значения, а запрашиваете состояние. Эти предикаты предназначены именно для работы с состоянием неопределённости и возвращают строго TRUE или FALSE.

0️⃣ Поведение агрегатных функций

Большинство агрегатов (SUM, AVG, MAX, MIN) игнорируют NULL. Это не ошибка, это следствие семантики "неизвестно":
➖ Если зарплата неизвестна, её нельзя включать в среднее - это исказит реальность.
➖ Если дата рождения неизвестна, нельзя сказать, кто самый старший.

Пример:
Таблица salaries:
id | amount
1 | 5000
2 | NULL
3 | 7000

Запрос:
SELECT AVG(amount) FROM salaries;  -- Результат: 6000 (а не 4000!)

Если вы сознательно хотите трактовать NULL как 0 (например, "не заплатили - значит, ноль"), используйте COALESCE или CASE:
SELECT AVG(COALESCE(amount, 0)) FROM salaries;  -- Теперь: 4000

Но будьте осторожны, это меняет семантику данных. Вы переходите от "мы не знаем" к "мы знаем, что это ноль"

0️⃣ NULL в JOIN, GROUP BY и ORDER BY

➖ JOIN. Строка с NULL в ключе не совпадёт ни с чем - даже с другой NULL. Потому что NULL = NULL - UNKNOWN, а не TRUE.
➖ GROUP BY. Все NULL в одном столбце группируются в одну группу. Это практичное исключение - иначе агрегация была бы бесполезной.
➖ORDER BY. NULL обычно идут в начале (ASC) или в конце (DESC), но это зависит от СУБД. В PostgreSQL можно управлять:
ORDER BY column NULLS LAST


0️⃣ Практические рекомендации

➖ Никогда не используйте = NULL - только IS NULL / IS NOT NULL.
➖ Явно обрабатывайте NULL в расчётах, если семантика требует замены (через COALESCE, CASE, NULLIF).
➖ Избегайте NOT IN, если подзапрос может вернуть NULL - это классическая ловушка: если в t2. id есть хотя бы один NULL, весь результат будет пустым! Лучше NOT EXISTS или LEFT JOIN ... WHERE t2. id IS NULL.
➖ При проектировании таблицы задайте вопрос: "Это поле может быть неизвестным - или просто необязательным?". Иногда лучше использовать отдельный флаг (is_age_estimated BOOLEAN).

#SQL #NULL

📱 Подписаться на канал
💻 Курс автора по SQL DDL
🌎 Мой ИТ-стартап
  • 🔥 27
  • 👾 4
  • 💯 3
  • 🌚 1
More from @relational_databases
  1. Oct 4, 2026❗️ Как найти дубли и оставить последнюю запись Одна из самых частых задач аналитика, это п…
  2. Jun 28, 2026Краткий справочник по типам данных к посту
  3. Jun 28, 2026👩‍💻 Типы данных в PostgreSQL: как они устроены и почему их выбор имеет значение Одна из…
  4. May 3, 2026Всем привет)) Я вернулся, так что с этой недели будут новые посты, будем воскрешать канал.…
  5. Dec 31, 2025🥳Всех с наступающим! Решил подвести, итоги года для канала. Создавая его в феврале, я даж…
  6. Oct 31, 2025💡 Реляционная модель, это не просто таблицы. Это договор между людьми Когда я только нача…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →