TGViewer
SQL Ready | Базы Данных SQL Ready | Базы Данных @sql_ready · 17.5K subscribers
Post #1593 2.15K
NULL и NOT IN — тонкость SQL, приводящая к логическим ошибкам!

При использовании NOT IN в SQL можно получить логически неверный результат без ошибок выполнения. Причина — трёхзначная логика и наличие NULL в данных.

Представим таблицы:
customers(id)
orders(id, customer_id)


Нужно найти клиентов, у которых нет заказов.

Интуитивный вариант:
SELECT id
FROM customers
WHERE id NOT IN (
SELECT customer_id
FROM orders
);


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

Это происходит потому, что NOT IN сводится к серии сравнений, а любое сравнение с NULL возвращает неопределённый результат.

Попытка исправить ситуацию фильтрацией:
SELECT id
FROM customers
WHERE id NOT IN (
SELECT customer_id
FROM orders
WHERE customer_id IS NOT NULL
);


Формально запрос корректен, но требует постоянного контроля и легко ломается при изменении подзапроса.

Надёжный вариант — использовать NOT EXISTS:
SELECT c.id
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
);


NOT EXISTS корректно обрабатывает NULL и предназначен именно для проверок отсутствия связанных строк.

🔥 Используй NOT EXISTS для анти-джойнов и проверок отсутствия данных, а NOT IN — только при полном контроле результата подзапроса.

➡️ SQL Ready | #практика
  • 👍 14
  • ❤ 8
  • 🤝 7
More from @sql_ready
  1. Oct 8, 2026Почему UNIQUE допускает несколько NULL в PostgreSQL! Ограничение UNIQUE гарантирует уникал…
  2. Oct 7, 2026📂 Шпаргалка по паттернам распределённых систем! Например, Replication повышает доступност…
  3. Oct 6, 2026Проверяйте связи с учётом периода! В PostgreSQL 18 связь может учитывать ещё и период его…
  4. Oct 6, 2026⚡️5 фундаментальных курсов по ИБ по цене одного Это предложение для тех, кто готов войти в…
  5. Oct 6, 2026👍 Устройство PostgreSQL — подробная документация на русском языке! Материалы посвящены не…
  6. Oct 5, 2026COUNT(*) в PostgreSQL: MVCC, visibility map и стоимость выполнения! В PostgreSQL точный CO…
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 →