
Оператор EXCEPT используется для сравнения двух результирующих выборок и возвращает строки, которые присутствуют в первой, но отсутствуют во второй. Такой подход удобен, когда требуется исключить дубликаты между запросами и получить только уникальные записи. В отличие от объединения UNION, которое складывает результаты, EXCEPT концентрируется на разнице.
Синтаксис выглядит просто: сначала указывается первый SELECT, затем второй, после чего применяется EXCEPT. Важно, чтобы оба запроса имели одинаковое количество столбцов и совпадали их типы данных. Несоблюдение этих условий приведет к ошибке выполнения.
Рассмотрим пример: есть таблицы employees_2024 и employees_2025. Чтобы найти сотрудников, которые работали в 2024 году, но не перешли в 2025, достаточно написать:
SELECT name FROM employees_2024
EXCEPT
SELECT name FROM employees_2025;
Результат вернет только тех сотрудников, которые исчезли из второй таблицы. Такой инструмент полезен при анализе изменений в данных – например, для выявления оттока клиентов, проверки пересечений наборов или контроля целостности справочников.
Как работает оператор EXCEPT в SQL

EXCEPT формирует выборку строк из первого запроса, которых нет во втором. Дублирующиеся строки удаляются, так как результат всегда содержит только уникальные записи.
Оба запроса в конструкции должны возвращать одинаковое количество столбцов с совместимыми типами данных. Имена столбцов берутся из первой выборки.
Пример:
SELECT id, name FROM clients
EXCEPT
SELECT id, name FROM archived_clients;
Результат – клиенты, которых нет в архивной таблице.
Если требуется сохранить повторяющиеся строки, в некоторых СУБД используется вариант EXCEPT ALL, где совпадения учитываются с точностью до количества вхождений.
EXCEPT часто применяют для поиска расхождений между таблицами, проверки корректности миграций и выявления отсутствующих записей при синхронизации данных.
Сравнение множеств строк при помощи EXCEPT

Оператор EXCEPT позволяет получить строки из одного запроса, которые отсутствуют в другом. Он работает только с результатами запросов, имеющими одинаковое количество столбцов и совместимые типы данных.
Пример использования: если есть таблицы Orders2024 и Orders2025, можно определить новые заказы текущего года:
SELECT OrderID, CustomerID FROM Orders2025
EXCEPT
SELECT OrderID, CustomerID FROM Orders2024;
Результат будет содержать только те OrderID, которые появились в 2025 году и отсутствовали в 2024.
При сравнении множеств строк EXCEPT автоматически удаляет дубликаты. Если требуется сохранить все экземпляры, следует использовать EXCEPT ALL, если СУБД поддерживает эту конструкцию.
Для корректного сравнения следует обеспечить одинаковый порядок и типы столбцов, иначе СУБД выдаст ошибку. Также важно учитывать, что NULL значения обрабатываются как равные друг другу.
EXCEPT эффективен для выявления различий между двумя выборками, контроля изменений данных и создания отчетов об исключениях. Для анализа больших таблиц рекомендуется применять индексы на сравниваемые поля, чтобы сократить время выполнения запроса.
Правила выбора столбцов для корректного использования

Оператор EXCEPT сравнивает строки двух запросов по соответствующим столбцам. Количество и порядок столбцов в обеих выборках должны полностью совпадать. Если первый запрос возвращает три столбца, второй также обязан возвращать три столбца с совместимыми типами данных.
Типы данных должны быть совместимыми: числовые с числовыми, строковые с строковыми. Приведение типов допустимо через CAST или CONVERT, но это может замедлить выполнение запроса.
Имена столбцов в результирующем наборе берутся из первого запроса. Второй запрос влияет только на фильтрацию строк, поэтому его названия не важны для результата.
Для предотвращения ошибок сравнения рекомендуется использовать одинаковый порядок столбцов в обеих выборках. Любое смещение приведет к логическим несоответствиям и может вернуть пустой результат.
При работе с NULL-значениями учитывайте, что EXCEPT считает NULL равными друг другу. Это важно при выборе столбцов: если столбец часто содержит NULL, его наличие может изменить итоговый набор строк.
Если в выборках присутствуют вычисляемые столбцы, их выражения должны быть идентичными по типу и позиции. Разные выражения могут быть допустимы, только если они приводят к одинаковому типу данных и соответствуют порядку столбцов.
Какие типы данных должны совпадать в обоих запросах
Оператор EXCEPT сравнивает строки двух запросов и возвращает только уникальные записи из первого запроса, которые отсутствуют во втором. Для корректной работы необходимо, чтобы столбцы в обоих запросах имели совместимые типы данных.
Требования к типам данных:
- Количество столбцов в обоих запросах должно совпадать.
- Позиции столбцов сравниваются последовательно: первый столбец первого запроса с первым столбцом второго запроса и так далее.
- Типы данных должны быть совместимыми или преобразуемыми без потери информации.
Примеры совместимых типов данных:
INTEGER↔NUMERIC,DECIMALCHAR(n)↔VARCHAR(n)DATE↔TIMESTAMP(если время не критично)
Примеры несовместимых типов:
INTEGER↔VARCHARбез явного преобразованияDATE↔INTEGERBLOB↔ любой другой тип
Рекомендации:
- Явно использовать
CASTилиCONVERT, если типы различаются, например:CAST(col AS VARCHAR(50)). - Проверять длину и точность числовых и символьных типов, чтобы избежать усечения данных.
- Сохранять последовательность столбцов строго одинаковой в обоих запросах.
Как EXCEPT удаляет дубликаты и влияет на результат
Оператор EXCEPT сравнивает строки двух запросов и возвращает только уникальные записи из первого набора, которых нет во втором. SQL автоматически выполняет удаление дубликатов перед сравнением, независимо от наличия ключей или индексов.
Например, если первый запрос возвращает 100 строк с 10 дубликатами, а второй запрос содержит 5 совпадающих строк, результат EXCEPT будет включать только уникальные строки, которых нет во втором наборе. Дубликаты из первого набора не повторяются в итоговом результате.
EXCEPT действует как комбинация DISTINCT и логического вычитания: сначала отбрасываются дубликаты в каждом наборе, затем выполняется сравнение. Это означает, что результаты всегда уникальны, даже если исходные запросы возвращают повторяющиеся строки.
При работе с большими таблицами использование EXCEPT требует учитывать, что операция удаления дубликатов увеличивает нагрузку на память и время выполнения. В случаях, когда дубликаты заранее несущественны, лучше использовать JOIN с условием NOT IN или NOT EXISTS, чтобы уменьшить затраты на сортировку и фильтрацию.
EXCEPT также чувствителен к типам данных и регистру: строки с одинаковыми значениями, но различающиеся регистром или форматом, считаются разными, и дубликаты не удаляются. Для контроля этого поведения рекомендуется применять CAST или функции нормализации текста.
При составлении запросов с EXCEPT важно учитывать порядок столбцов: сравнение выполняется посрочно и по позиции, а не по имени столбца. Несоответствие структуры приведет к ошибке, даже если данные дублируются по содержимому.
Отличия между EXCEPT и EXCEPT ALL
Оператор EXCEPT возвращает уникальные строки из первого набора данных, которых нет во втором. Все дубликаты автоматически удаляются. Например, если в первой таблице три одинаковые строки, а во второй одна из них совпадает, результатом EXCEPT будет одна строка, оставшаяся после исключения.
EXCEPT ALL сохраняет все дубликаты из первого набора данных, за исключением тех, которые встречаются во втором. Если первая таблица содержит три одинаковые строки, а во второй одна из них совпадает, результатом будет две строки – разница по количеству повторений. Это позволяет учитывать частотные распределения данных.
Использование EXCEPT целесообразно, когда важны только уникальные значения и требуется убрать любые повторы. EXCEPT ALL применяют, когда нужно сохранить точное количество вхождений, отличающихся от второго набора.
С точки зрения производительности, EXCEPT требует дополнительной сортировки или хэширования для удаления дубликатов, тогда как EXCEPT ALL выполняется быстрее на больших наборах с множеством повторов, так как шаг удаления дубликатов пропускается.
Рекомендация: для анализа точной разницы с учетом повторов используйте EXCEPT ALL, для фильтрации уникальных элементов – EXCEPT. Это минимизирует ошибки при агрегации и подсчете данных.
Разбор различий EXCEPT и операторов UNION/INTERSECT
Оператор EXCEPT возвращает строки из первой выборки, которых нет во второй. В отличие от него, UNION объединяет результаты двух запросов, удаляя дубликаты, а UNION ALL сохраняет все строки, включая повторяющиеся. INTERSECT возвращает только общие строки между выборками.
EXCEPT часто используют для выявления исключений или несоответствий между таблицами. Например, чтобы найти клиентов, которые сделали заказ в 2024, но отсутствуют в таблице текущих активных клиентов:
SELECT client_id FROM orders_2024 EXCEPT SELECT client_id FROM active_clients;
Важное отличие заключается в порядке обработки данных. UNION и INTERSECT сравнивают все строки обеих выборок и автоматически удаляют дубликаты, что может влиять на производительность при больших объемах. EXCEPT выполняет фильтрацию только первой выборки относительно второй.
Все три оператора требуют одинаковой структуры столбцов и совместимых типов данных. Однако при работе с EXCEPT следует помнить: результат всегда исключает дубликаты, поэтому для сохранения повторяющихся строк нужно использовать EXCEPT ALL (поддерживается не во всех СУБД).
В рекомендациях по выбору оператора: используйте EXCEPT для выявления различий, INTERSECT – для поиска пересечений, UNION – для объединения данных без дубликатов. Для оптимизации запросов проверяйте индексы и минимизируйте объем данных перед применением этих операторов, так как они выполняют сопоставление строк на уровне всей выборки.
Примеры применения EXCEPT для поиска отсутствующих записей
Оператор EXCEPT используется для выявления строк, присутствующих в одном запросе, но отсутствующих в другом. Это особенно удобно для контроля данных между таблицами с одинаковой структурой.
Рассмотрим таблицы employees и terminated_employees. Необходимо получить список действующих сотрудников, которых нет в таблице уволенных:
SELECT employee_id, name FROM employees
EXCEPT
SELECT employee_id, name FROM terminated_employees;
Результат возвращает только тех сотрудников, которые отсутствуют в списке уволенных. Для анализа можно дополнительно ограничивать колонки или добавлять фильтры по отделам:
SELECT employee_id, name, department FROM employees WHERE department = 'Sales'
EXCEPT
SELECT employee_id, name, department FROM terminated_employees;
Пример с таблицами заказов orders_2024 и orders_2025 позволяет определить заказы, которые не повторились в следующем году:
SELECT order_id, customer_id FROM orders_2024
EXCEPT
SELECT order_id, customer_id FROM orders_2025;
| Таблица | Описание | Применение |
|---|---|---|
| employees / terminated_employees | Сотрудники и уволенные | Выявление действующих сотрудников |
| orders_2024 / orders_2025 | Заказы двух годов | Поиск заказов, не повторившихся в новом году |
| products / discontinued_products | Товары и снятые с производства | Список доступных товаров |
Важно, чтобы столбцы в обеих выборках совпадали по типу и количеству. Оператор EXCEPT автоматически исключает дубликаты, поэтому использование DISTINCT избыточно. Для сохранения порядка рекомендуется добавлять ORDER BY в основном запросе.
Ограничения и частые ошибки при работе с EXCEPT

Оператор EXCEPT возвращает строки, присутствующие в первой выборке, но отсутствующие во второй. Его использование имеет специфические ограничения, которые важно учитывать для корректной работы запросов.
- Совпадение количества и типов столбцов: Обе выборки должны содержать одинаковое количество столбцов с совместимыми типами данных. Несоответствие вызывает ошибку выполнения.
- Сортировка результатов:
EXCEPTне гарантирует порядок строк. Для упорядочивания нужно использоватьORDER BYпосле всего выражения. - NULL значения: В SQL NULL при сравнении считается особым значением. Две строки с NULL в одном столбце могут считаться идентичными, но поведение зависит от конкретной СУБД.
- Дублирование строк:
EXCEPTпо умолчанию убирает дубликаты. Чтобы сохранить все строки, следует использоватьEXCEPT ALL, если СУБД поддерживает эту форму. - Подзапросы и производительность: Использование
EXCEPTс большими подзапросами может приводить к высоким затратам на сортировку и хэширование. Оптимизация индексов и фильтров ускоряет выполнение.
Частые ошибки при работе с EXCEPT:
- Несовпадение количества столбцов в двух выборках.
- Попытка сравнить несовместимые типы данных, например
INTиVARCHAR. - Ожидание сохранения исходного порядка строк без
ORDER BY. - Неучёт поведения NULL, что может приводить к неожиданным результатам.
- Использование
EXCEPTв сложных подзапросах без индексов, что замедляет выполнение.
Рекомендации:
- Всегда проверяйте количество и типы столбцов перед применением
EXCEPT. - Если порядок строк важен, добавляйте
ORDER BYпосле выражения. - При работе с NULL учитывайте особенности СУБД и тестируйте поведение на примерах с пустыми значениями.
- Для больших таблиц оптимизируйте выборки с фильтрами и индексами, чтобы снизить нагрузку на систему.
- Используйте
EXCEPT ALL, если необходимо сохранить дубликаты.
Вопрос-ответ:
Что делает оператор EXCEPT в SQL и как его использовать?
Оператор EXCEPT позволяет получить строки, которые присутствуют в первой выборке, но отсутствуют во второй. Например, если есть таблица сотрудников и таблица бывших сотрудников, с помощью EXCEPT можно получить список активных сотрудников, исключив тех, кто уже ушел. Синтаксис простой: SELECT столбцы FROM таблица1 EXCEPT SELECT столбцы FROM таблица2.
Можно ли использовать EXCEPT с более чем двумя запросами?
Да, SQL допускает последовательное использование нескольких операторов EXCEPT. Например, можно написать SELECT A FROM T1 EXCEPT SELECT B FROM T2 EXCEPT SELECT C FROM T3. Оператор всегда сравнивает строки по позициям столбцов и возвращает уникальные строки, которые встречаются только в первой выборке на каждом шаге. Каждое следующее исключение применяется к результату предыдущего шага.
Как EXCEPT обрабатывает дубликаты строк?
По умолчанию EXCEPT возвращает уникальные строки, то есть дубликаты отбрасываются. Если в первой выборке одна и та же строка встречается несколько раз, но во второй выборке она отсутствует, результат всё равно будет содержать её только один раз. В некоторых диалектах SQL можно использовать EXCEPT ALL, чтобы сохранить повторяющиеся строки и получить более точный контроль над результатом.
Какие требования к структуре столбцов у запросов при использовании EXCEPT?
Для работы EXCEPT обе выборки должны иметь одинаковое количество столбцов, и типы данных соответствующих столбцов должны быть совместимы. Позиции столбцов имеют значение: SQL сравнивает строки по порядку столбцов, а не по их именам. Если структура не совпадает, база данных выдаст ошибку.
В чём отличие EXCEPT от JOIN или подзапросов с NOT IN?
Основное отличие в подходе: EXCEPT возвращает строки, которые полностью отсутствуют во второй выборке, без необходимости использовать соединения или подзапросы. JOIN требует объединения таблиц и явного условия, а NOT IN проверяет каждый элемент списка. EXCEPT часто короче и нагляднее, когда нужно сравнить две таблицы по всем столбцам сразу. При этом производительность может различаться в зависимости от СУБД и объема данных.
