- Home »

SQL IN и SQL NOT IN — использование и примеры
Сегодня разберёмся с двумя простыми, но крайне полезными SQL-операторами — IN и NOT IN. Если ты когда-нибудь пытался фильтровать данные по списку значений или, наоборот, исключить определённые элементы, то наверняка сталкивался с этими конструкциями. Почему это важно? Потому что грамотное использование IN и NOT IN экономит кучу времени, упрощает запросы и делает их более читаемыми. А если ты настраиваешь сервер, автоматизируешь бэкапы, мониторинг или просто хочешь быстро выцепить нужные строки из базы — эти операторы станут твоими лучшими друзьями. В этой статье — всё, что нужно знать: как работают IN и NOT IN, как их быстро внедрить, какие подводные камни бывают, и как не наступить на грабли. Погнали!
Как это работает? — Механика IN и NOT IN
Оператор IN в SQL — это способ сказать: «Дай мне все строки, где значение в этом столбце совпадает с любым из перечисленных». По сути, это синтаксический сахар для длинной цепочки OR. Например:
SELECT * FROM users WHERE country IN ('RU', 'UA', 'BY');
Это то же самое, что:
SELECT * FROM users WHERE country = 'RU' OR country = 'UA' OR country = 'BY';
NOT IN — противоположность. Он вернёт строки, где значение не содержится в списке:
SELECT * FROM users WHERE country NOT IN ('RU', 'UA', 'BY');
Выглядит просто? Так и есть. Но есть нюансы, о которых часто забывают даже опытные админы.
- IN работает с любым количеством значений (от одного до сотен).
- Можно использовать подзапросы:
IN (SELECT ...)
- Типы данных должны совпадать (иначе будет implicit cast или ошибка).
- NULL внутри списка — особый случай (подробнее ниже).
Как быстро и просто всё настроить?
Если у тебя уже есть сервер с MySQL, PostgreSQL или даже SQLite — всё, что нужно, это доступ к консоли или GUI (phpMyAdmin, DBeaver, DataGrip и т.д.). IN и NOT IN поддерживаются всеми популярными СУБД. Примеры ниже универсальны, но нюансы есть (особенно с NULL и производительностью).
- Открываешь консоль или GUI.
- Пишешь SELECT с IN или NOT IN.
- Проверяешь результат, радуешься.
Если хочется автоматизировать — можно использовать эти операторы в скриптах (bash + psql/mysql), в cron-задачах, в Python (через SQLAlchemy или psycopg2), в PHP, Node.js и т.д. Всё зависит от твоей инфраструктуры.
Примеры, схемы, практические советы
Давай разберём реальные кейсы. Вот таблица users:
id | name | country | status
---+---------+---------+--------
1 | Ivan | RU | active
2 | John | US | blocked
3 | Olga | UA | active
4 | Petr | BY | pending
5 | Alice | US | active
6 | Sergey | RU | blocked
Задача 1: Найти всех пользователей из России, Украины и Беларуси.
SELECT * FROM users WHERE country IN ('RU', 'UA', 'BY');
Задача 2: Найти всех, кто не из этих стран.
SELECT * FROM users WHERE country NOT IN ('RU', 'UA', 'BY');
Задача 3: Найти всех активных пользователей, кроме тех, кто из России.
SELECT * FROM users WHERE status = 'active' AND country NOT IN ('RU');
Задача 4: Использовать подзапрос — найти пользователей, у которых есть заказы (таблица orders, поле user_id):
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
Задача 5: Исключить пользователей, у которых есть заказы:
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);
Положительные и отрицательные кейсы
Кейс | IN / NOT IN | Плюсы | Минусы | Рекомендации |
---|---|---|---|---|
Фильтрация по списку стран | IN | Просто, читаемо, быстро | Список длиннее 1000 — может тормозить | Для коротких списков — идеально |
Исключение по статусу | NOT IN | Просто, читаемо | NULL в списке — все строки пропадут | Следи за NULL, используй IS NULL отдельно |
Сравнение с подзапросом | IN (SELECT …) | Гибко, удобно | Может быть медленно на больших таблицах | Добавь индекс на подзапрос |
Большой список (10000+) | IN | Работает, но… | Может быть очень медленно | Вставь значения во временную таблицу и делай JOIN |
NULL — подводный камень
Если в списке IN или NOT IN есть NULL, результат может быть неожиданным. Например:
SELECT * FROM users WHERE country NOT IN ('RU', NULL);
Ты ожидаешь увидеть всех, кто не из России, но… не увидишь вообще никого! Потому что сравнение с NULL всегда даёт UNKNOWN, и строка не попадает в результат. Поэтому:
- Не добавляй NULL в список IN/NOT IN.
- Для поиска NULL используй
IS NULL
илиIS NOT NULL
.
Команды и синтаксис
-- Простой IN
SELECT * FROM table WHERE column IN (value1, value2, value3);
-- NOT IN
SELECT * FROM table WHERE column NOT IN (value1, value2);
-- IN с подзапросом
SELECT * FROM table WHERE column IN (SELECT other_column FROM other_table);
-- NOT IN с подзапросом
SELECT * FROM table WHERE column NOT IN (SELECT other_column FROM other_table);
-- IN с числовыми значениями
SELECT * FROM table WHERE id IN (1, 2, 3, 4, 5);
-- IN с текстовыми значениями
SELECT * FROM table WHERE name IN ('Alice', 'Bob', 'Charlie');
Похожие решения, программы и утилиты
- JOIN — если список значений большой, лучше использовать временную таблицу и делать
INNER JOIN
илиLEFT JOIN
. - EXISTS / NOT EXISTS — альтернатива IN/NOT IN для подзапросов, часто быстрее на больших данных.
- INTERSECT — если нужно пересечение двух выборок (PostgreSQL, Oracle).
- UNION — если нужно объединить результаты разных запросов.
- GUI-инструменты: DBeaver, pgAdmin, DB Browser for SQLite.
Статистика и сравнение с другими решениями
- IN быстрее, чем длинная цепочка OR (особенно на коротких списках).
- NOT IN с подзапросом — медленно, если подзапрос возвращает много строк и есть NULL.
- EXISTS обычно быстрее NOT IN на больших таблицах.
- JOIN — лучший выбор для больших списков (1000+ значений).
Метод | Короткий список | Большой список | С подзапросом | NULL-friendly |
---|---|---|---|---|
IN | ++ | + | + | – |
NOT IN | ++ | + | – | — |
EXISTS | + | ++ | ++ | ++ |
JOIN | + | ++ | ++ | ++ |
Интересные факты и нестандартные способы использования
- Можно использовать IN для фильтрации по подмножеству IP-адресов, если хранить их как строки.
- IN отлично работает в триггерах и процедурах для массовых обновлений.
- В PostgreSQL можно использовать массивы:
WHERE column = ANY(ARRAY[...])
— аналог IN, но с возможностью динамического формирования списка. - В MySQL можно генерировать список значений динамически через GROUP_CONCAT и потом использовать в IN (например, для сложных автоматизаций).
- В автоматизации (bash + psql/mysql) можно формировать список значений на лету, подставлять в IN и делать массовые операции (например, удалять пользователей по списку ID из файла).
Новые возможности для автоматизации и скриптов
- Массовое обновление/удаление/выборка по списку ID из файла или API.
- Интеграция с системами мониторинга: быстро исключать/включать группы серверов по статусу или тегу.
- Гибкая фильтрация данных для отчётов, резервного копирования, миграций.
- Автоматизация очистки логов, временных данных, блокировки пользователей по списку.
- Скрипты для CI/CD: выборка нужных записей для деплоя, тестов, миграций.
Вывод — заключение и рекомендации
IN и NOT IN — это must-have инструменты для любого, кто работает с SQL. Они просты, читаемы и позволяют быстро фильтровать данные по списку значений. Для коротких списков — идеальны. Для больших — лучше использовать временные таблицы и JOIN. Не забывай про NULL: если он затесался в твой список, результат может быть неожиданным. Для подзапросов и больших данных — смотри в сторону EXISTS и JOIN. В автоматизации IN/NOT IN — незаменимы: позволяют быстро делать массовые операции, интегрироваться с внешними системами, строить гибкие скрипты.
Если ты ищешь, где всё это можно попробовать на практике — VPS или выделенный сервер — твой выбор. Настраивай, экспериментируй, автоматизируй!
Официальная документация для глубокого погружения:
Пробуй, экспериментируй, и пусть твои запросы всегда будут быстрыми и красивыми!
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.