IN и NOT IN для множеств
Фильтруйте по спискам значений с помощью IN и NOT IN, узнайте о проблеме NULL в NOT IN и заменяйте его на EXISTS для безопасной семантики
«IN и NOT IN для множеств» — бесплатный урок SQL Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
IN: сопоставление со списком
IN — это сокращённая запись множества условий OR:
SELECT * FROM users WHERE country IN ('US', 'CA', 'GB');
-- Equivalent to:
SELECT * FROM users
WHERE country = 'US' OR country = 'CA' OR country = 'GB';IN с подзапросом
В правой части можно использовать подзапрос:
SELECT * FROM orders
WHERE user_id IN (
SELECT id FROM users WHERE country = 'US'
);NOT IN: исключение списка
Отфильтруйте строки, соответствующие условию:
SELECT * FROM users WHERE status NOT IN ('banned', 'deleted');Ловушка NULL в NOT IN
Если правая часть содержит NULL, NOT IN возвращает NULL, а строки, в которых предикат равен NULL, отбрасываются. Результат: ноль строк.
-- Suppose blocked_names contains NULL:
SELECT name FROM users
WHERE name NOT IN (SELECT excluded_name FROM blocked_names);
-- → 0 rows, silently
-- Safer: filter out NULLs explicitly, or use NOT EXISTS:
SELECT name FROM users u
WHERE NOT EXISTS (
SELECT 1 FROM blocked_names b WHERE b.excluded_name = u.name
);Почему NOT EXISTS безопаснее
NOT EXISTS использует стандартную семантику коррелированных подзапросов и безопасен при наличии NULL. Большинство планировщиков оптимизируют его так же, как корректно сформированный NOT IN.
IN и OR — удобство чтения
IN понятнее длинных цепочек OR, и планировщик часто оптимизирует их одинаково:
-- Hard to read:
WHERE country = 'US' OR country = 'CA' OR country = 'GB' OR ...
-- Clear:
WHERE country IN ('US', 'CA', 'GB', ...)IN с кортежами (конструкторами строк)
Сопоставление пар столбцов:
SELECT * FROM order_items
WHERE (order_id, product_id) IN (
(1, 42), (2, 99), (3, 17)
);Использование индексов
Список IN для индексированного столбца можно выполнить как несколько обращений к индексу (сканирование индекса по битовой карте). Обычно это работает быстро.
-- Plan: Bitmap Index Scan + Bitmap Heap Scan
SELECT * FROM products WHERE id IN (1, 5, 99, 121, 4421);Большие списки IN
Списки из тысяч значений могут работать медленно. Предпочтительнее:
- JOIN с обычной или временной таблицей
= ANY(array)для передачи параметра-массива
SELECT * FROM products WHERE id = ANY(ARRAY[1,2,3,...]);IN с пустым списком
Пустой список IN недопустим в стандартном SQL. Некоторые клиенты передают специальное маркерное значение; безопаснее формировать условие SQL условно.
-- Use empty array trick in PostgreSQL:
SELECT * FROM products WHERE id = ANY($1::bigint[]);
-- Pass {} to get zero matches without rewriting the SQL.IN и JOIN
Иногда JOIN понятнее, чем IN с подзапросом:
-- With IN:
SELECT * FROM orders
WHERE user_id IN (SELECT id FROM users WHERE pro);
-- With JOIN:
SELECT o.*
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE u.pro;Итоги
IN — удобная форма проверки принадлежности множеству.
- Используйте IN вместо OR для удобства чтения
- NOT IN опасен при наличии NULL — предпочитайте NOT EXISTS
- Для больших множеств используйте JOIN или передавайте массивы
Быстрая проверка
Как безопаснее всего заменить NOT IN (subquery), если подзапрос может содержать NULL?
Часто задаваемые вопросы
Урок «IN и NOT IN для множеств» бесплатный?
Да — полный текст урока «IN и NOT IN для множеств» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «IN и NOT IN для множеств»?
Фильтруйте по спискам значений с помощью IN и NOT IN, узнайте о проблеме NULL в NOT IN и заменяйте его на EXISTS для безопасной семантики Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «IN и NOT IN для множеств»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Шаблоны LIKE и подстановочные символы
- IN и NOT IN для множеств
- BETWEEN для диапазонов
- IS NULL, IS NOT NULL и COALESCE