TGViewer
SQL Ready | Базы Данных SQL Ready | Базы Данных @sql_ready · 17.5K subscribers
Post #2046 1.85K
IS DISTINCT FROM — сравнение значений с NULL!

NULL обозначает отсутствие известного значения, поэтому стандартные операторы сравнения = и <> не позволяют корректно определить равенство или различие, если один из операндов содержит NULL.
Например:
NULL <> 'new value'


Результатом выражения будет NULL, а не TRUE или FALSE. Это связано с трёхзначной логикой SQL: результат сравнения с неизвестным значением также является неизвестным.

Поэтому проверки изменения данных с использованием обычных операторов сравнения требуют дополнительной обработки:
column <> new_value
OR (column IS NULL AND new_value IS NOT NULL)
OR (column IS NOT NULL AND new_value IS NULL)


Оператор IS DISTINCT FROM решает эту задачу, выполняя сравнение с явным учетом NULL и всегда возвращая логическое значение. Пример обновления пользователя только при фактическом изменении email:
UPDATE users
SET email = :new_email
WHERE id = :id
AND email IS DISTINCT FROM :new_email;


Если значения совпадают, строка обновлена не будет. Если одно значение содержит NULL, а другое — данные, оператор определит их как различные.

Оператор также корректно обрабатывает случай, когда оба значения равны NULL:
SELECT NULL IS DISTINCT FROM NULL;


Результат:
false


В логике IS DISTINCT FROM два значения NULL считаются одинаковыми, так как оба представляют отсутствие значения. Без использования данного оператора аналогичная проверка требует дополнительных условий:
email <> :new_email
OR (email IS NULL AND :new_email IS NOT NULL)
OR (email IS NOT NULL AND :new_email IS NULL)


IS DISTINCT FROM заменяет такую конструкцию одним выражением и делает сравнение nullable-полей более предсказуемым.

При обновлении сущностей через API, синхронизации данных и импорте часто возникает ситуация, когда передаётся полный объект, хотя часть полей не изменилась. Обычный запрос:
UPDATE users
SET
email = :new_email,
name = :new_name
WHERE id = :id;


выполнит обновление независимо от фактического изменения значений.

В PostgreSQL это приводит к созданию новой версии строки в рамках MVCC, увеличению объёма WAL, дополнительным вызовам триггеров и генерации ненужных событий при использовании репликации или систем обработки изменений. Более точный вариант:
UPDATE users
SET
email = :new_email,
name = :new_name
WHERE id = :id
AND (
email IS DISTINCT FROM :new_email
OR name IS DISTINCT FROM :new_name
);


Такой подход позволяет выполнять обновление только при изменении данных. Он применяется в API, системах синхронизации, импортерах данных и интеграционных процессах.

🔥 IS DISTINCT FROM — оператор, который обеспечивает корректное сравнение значений с NULL и помогает избегать лишних операций записи в базе данных.

➡️ SQL Ready | #практика
  • ❤ 15
  • 👍 7
  • 🔥 5
  • 🤝 1
More from @sql_ready
  1. Oct 5, 2026COUNT(*) в PostgreSQL: MVCC, visibility map и стоимость выполнения! В PostgreSQL точный CO…
  2. Oct 5, 2026Как оплачивать зарубежные сервисы в 2026 году? Можно бегать между посредниками и бояться б…
  3. Oct 5, 2026Проверяйте JSON без преобразования! Если JSON приходит как text, необязательно делать ::js…
  4. Oct 2, 2026Настройте оценку пользовательских функций! Для пользовательской функции PostgreSQL позволя…
  5. Oct 2, 2026😍 SQL-Tutorial — бесплатный учебник по SQL с практическими заданиями! Онлайн-учебник для…
  6. Oct 1, 2026🐱 PostgreSQL Course RU — курс по PostgreSQL и SQL для разработчиков! В репозитории собран…
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 →