Home » SQL IN и SQL NOT IN — использование и примеры
SQL IN и SQL NOT IN — использование и примеры

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 или выделенный сервер — твой выбор. Настраивай, экспериментируй, автоматизируй!

Официальная документация для глубокого погружения:

Пробуй, экспериментируй, и пусть твои запросы всегда будут быстрыми и красивыми!


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked