IN, ANY и ALL
Сравнивайте значения с наборами значений
«IN, ANY и ALL» — бесплатный урок SQL Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
Что такое IN, ANY и ALL?
При написании запросов SQL часто требуется сравнить значение с набором значений. Для этого SQL предоставляет три мощных оператора: IN, ANY и ALL.
Все три оператора могут работать с подзапросами, возвращающими список значений. Они выглядят похоже, но ведут себя по-разному — правильный выбор сделает запрос более выразительным и эффективным.
Оператор IN
Оператор IN проверяет, совпадает ли значение с каким-либо значением в списке или результате подзапроса. Это самый простой из трёх операторов.
Пример ниже возвращает сотрудников, работающих в отделах продаж, HR или инженерии.
SELECT name, department
FROM employees
WHERE department IN ('Sales', 'HR', 'Engineering');IN с подзапросом
IN становится особенно полезным в сочетании с подзапросом. Вместо заранее заданного списка можно получить значения для сравнения непосредственно из другой таблицы.
Здесь мы находим всех сотрудников, работающих в отделе с бюджетом более 100 000.
SELECT name, department
FROM employees
WHERE department IN (
SELECT dept_name
FROM departments
WHERE budget > 100000
);Оператор ANY
ANY (также записываемый как SOME) сравнивает значение с каждым значением, возвращённым подзапросом, используя оператор сравнения, например =, >, <, >= или <=.
Условие истинно, если сравнение выполняется хотя бы для одного значения в результате подзапроса.
SELECT name, salary
FROM employees
WHERE salary > ANY (
SELECT salary
FROM employees
WHERE department = 'HR'
);= ANY эквивалентно IN
Важно знать об этой эквивалентности: = ANY (subquery) логически идентично IN (subquery). Оба варианта возвращают истину, когда значение совпадает хотя бы с одним результатом подзапроса.
Эти два запроса дают одинаковый результат:
-- Using IN
SELECT name FROM employees
WHERE department_id IN (SELECT id FROM departments WHERE location = 'NYC');
-- Using = ANY
SELECT name FROM employees
WHERE department_id = ANY (SELECT id FROM departments WHERE location = 'NYC');Оператор ALL
ALL сравнивает значение с каждым значением в результате подзапроса. Условие истинно только в том случае, если сравнение выполняется для всех возвращённых значений.
В этом примере находятся сотрудники, чья зарплата выше любой зарплаты в категории стажёров, то есть выше зарплаты самого высокооплачиваемого стажёра.
SELECT name, salary
FROM employees
WHERE salary > ALL (
SELECT salary
FROM employees
WHERE job_grade = 'Intern'
);ANY и ALL — сравнение
Главное различие заключается в следующем: ANY требует, чтобы условие было истинным хотя бы для одного значения, а ALL — чтобы оно было истинным для каждого значения.
Представьте это так: ANY похож на OR для всех сравнений, а ALL — на AND для всех сравнений.
-- Returns rows where salary > at least one value in the subquery
SELECT name, salary FROM employees
WHERE salary > ANY (SELECT salary FROM employees WHERE department = 'Support');
-- Returns rows where salary > every value in the subquery
SELECT name, salary FROM employees
WHERE salary > ALL (SELECT salary FROM employees WHERE department = 'Support');NOT IN и <> ALL
Подобно тому как = ANY соответствует IN, оператор <> ALL эквивалентен NOT IN. Оба варианта возвращают истину только тогда, когда значение не совпадает ни с одним значением в подзапросе.
Однако будьте внимательны: если подзапрос возвращает хотя бы один NULL, NOT IN не вернёт ни одной строки из-за трёхзначной логики SQL.
-- Using NOT IN
SELECT name FROM employees
WHERE department_id NOT IN (SELECT id FROM departments WHERE location = 'Remote');
-- Using <> ALL (equivalent)
SELECT name FROM employees
WHERE department_id <> ALL (SELECT id FROM departments WHERE location = 'Remote');Ловушка NULL при использовании NOT IN
Есть одна важная особенность: если подзапрос, используемый с NOT IN, возвращает NULL, всё условие NOT IN для каждой строки принимает значение UNKNOWN, поэтому результат оказывается пустым.
Чтобы избежать этого, отфильтруйте NULL из подзапроса или используйте вместо него NOT EXISTS — этот оператор безопасно работает с NULL.
-- Dangerous: if manager_id has any NULL, no rows are returned
SELECT name FROM employees
WHERE id NOT IN (SELECT manager_id FROM employees);
-- Safe: filter NULLs explicitly
SELECT name FROM employees
WHERE id NOT IN (
SELECT manager_id FROM employees
WHERE manager_id IS NOT NULL
);Практический пример: поиск высокооплачиваемых сотрудников
Рассмотрим, как все три оператора применяются в реалистичном сценарии. У нас есть таблица employees со столбцами name, department и salary.
Нам нужны сотрудники, которые зарабатывают больше средней зарплаты хотя бы одного отдельного отдела, то есть больше средней зарплаты хотя бы одного отдела.
SELECT name, salary
FROM employees
WHERE salary > ANY (
SELECT AVG(salary)
FROM employees
GROUP BY department
)
ORDER BY salary DESC;Когда какой оператор использовать?
Вот краткое руководство по выбору одного из трёх операторов:
- IN — если у Вас есть статический список или нужно простое сопоставление на равенство с результатом подзапроса.
- = ANY — то же, что IN, но позволяет использовать другие операторы сравнения, например
>или<. - ALL — если условие должно выполняться для каждого значения (например, значение должно быть больше максимального без использования MAX).
- NOT IN — удобный оператор, но следите за NULL; предпочитайте
NOT EXISTS, если подзапрос может содержать NULL.
Быстрая проверка
Проверьте, насколько Вы поняли принципы работы IN, ANY и ALL.
Итоги урока
В этом уроке Вы узнали, как сравнивать значения с набором с помощью IN, ANY и ALL.
Основные выводы:
INпроверяет принадлежность — возвращает истину, если значение совпадает с каким-либо элементом списка или результата подзапроса.= ANYэквивалентенIN; использование других операторов, например> ANY, означает, что условие должно быть истинным хотя бы для одного совпадения.ALLозначает, что условие должно выполняться для каждого значения, возвращённого подзапросом.NOT INмолча не возвращает ни одной строки, если подзапрос содержит NULL; всегда учитывайте эту особенность.- Используйте
NOT EXISTSкак более безопасную альтернативуNOT IN, если могут присутствовать NULL.
Часто задаваемые вопросы
Урок «IN, ANY и ALL» бесплатный?
Да — полный текст урока «IN, ANY и ALL» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «IN, ANY и ALL»?
Сравнивайте значения с наборами значений Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «IN, ANY и ALL»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.