INTERSECT e EXCEPT: Operações de Conjunto no MySQL

Como usar os operadores INTERSECT e EXCEPT, adicionados no MySQL 8.0.31, para calcular interseções e diferenças entre resultados de consultas sem depender de JOINs complexos.

Até o MySQL 8.0.30, combinar os resultados de duas consultas com operações de conjunto só era possível com UNION. Quem precisava calcular uma interseção ou uma diferença entre dois resultados tinha que recorrer a JOINs, NOT EXISTS ou subqueries. A partir do MySQL 8.0.31, o banco ganhou os operadores INTERSECT e EXCEPT, completando o trio de operações de conjunto do padrão SQL junto com o já conhecido UNION.

Como funcionam

INTERSECT retorna apenas as linhas que aparecem nos dois resultados. EXCEPT retorna as linhas do primeiro resultado que não aparecem no segundo. As duas consultas envolvidas precisam ter o mesmo número de colunas, com tipos compatíveis, exatamente como já era exigido pelo UNION:

SELECT cliente_id FROM compras_2024
INTERSECT
SELECT cliente_id FROM compras_2025;

Essa consulta retorna os clientes que compraram tanto em 2024 quanto em 2025.

Exemplo com EXCEPT

Trocando o operador, dá para responder à pergunta oposta: quem comprou em 2024, mas não voltou a comprar em 2025 — útil para identificar clientes inativos:

SELECT cliente_id FROM compras_2024
EXCEPT
SELECT cliente_id FROM compras_2025;

A ordem importa: compras_2024 EXCEPT compras_2025 não é o mesmo que compras_2025 EXCEPT compras_2024.

DISTINCT e ALL

Assim como no UNION, o comportamento padrão remove duplicatas do resultado final. Isso equivale a escrever explicitamente INTERSECT DISTINCT ou EXCEPT DISTINCT. Para preservar duplicatas — por exemplo, para saber quantas vezes cada linha se repete na interseção — use a variante ALL:

SELECT produto_id FROM pedidos_loja_fisica
INTERSECT ALL
SELECT produto_id FROM pedidos_loja_online;

Com ALL, se um produto_id aparece 3 vezes em um lado e 2 vezes no outro, ele aparece 2 vezes no resultado (o menor dos dois).

Combinando os três operadores

É possível encadear UNION, INTERSECT e EXCEPT na mesma consulta. A precedência não é da esquerda para a direita: INTERSECT tem prioridade maior e é avaliado antes de UNION e EXCEPT, de forma parecida com a multiplicação em relação à soma:

SELECT cliente_id FROM leads
EXCEPT
SELECT cliente_id FROM compras_2024
INTERSECT
SELECT cliente_id FROM compras_2025;

Essa consulta é avaliada como leads EXCEPT (compras_2024 INTERSECT compras_2025). Quando a intenção não é óbvia, vale usar parênteses em torno de cada SELECT para deixar a ordem explícita e evitar surpresas.

Quando usar

Compatibilidade

INTERSECT e EXCEPT estão disponíveis a partir do MySQL 8.0.31 (outubro de 2022) e seguem presentes no MySQL 8.4 LTS e nas versões 9.x. Em versões anteriores a 8.0.31, esses operadores não existem e é preciso recorrer a JOINs ou subqueries para obter o mesmo resultado.

documentação oficial

Conclusão

INTERSECT e EXCEPT não fazem nada que não fosse possível antes com JOINs e subqueries, mas deixam a intenção da consulta muito mais clara e o SQL mais curto. Para comparações entre conjuntos de dados, vale conhecê-los antes de recorrer a soluções mais verbosas.

Tecnologia:
mysql

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.