0Pricing
SQL Interview Prep · Aula

Emulando operações de conjuntos com junções

Reescreva EXCEPT e INTERSECT em dialetos que não os oferecem.

Emulando operações de conjuntos com junções é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.

Por que reproduzir operações de conjuntos

Nem todo banco de dados oferece INTERSECT e EXCEPT. Versões antigas do MySQL, por exemplo, não os ofereciam de forma alguma. Os entrevistadores verificam se você consegue reproduzir a lógica de conjuntos com operações JOIN e subconsultas quando o operador não está disponível.

Conhecer tanto o operador de conjuntos quanto seu equivalente com JOIN demonstra que você entende o que o operador realmente calcula.

INTERSECT como um INNER JOIN

INTERSECT encontra as linhas comuns aos dois conjuntos. O equivalente com JOIN é um INNER JOIN sobre todas as colunas comparadas, além de DISTINCT para reproduzir o comportamento de deduplicação.

Cada coluna da comparação se torna parte do predicado da operação JOIN.

-- A INTERSECT B emulated:
SELECT DISTINCT a.customer_id
FROM orders_2023 a
JOIN orders_2024 b
  ON a.customer_id = b.customer_id;

Por que DISTINCT é necessário para INTERSECT

Um INNER JOIN simples pode expandir os resultados: se um valor aparecer várias vezes em qualquer um dos lados, a operação JOIN multiplicará as linhas. O INTERSECT padrão retorna cada linha comum uma única vez, portanto você adiciona DISTINCT para eliminar as duplicatas introduzidas pela operação JOIN.

Esquecer DISTINCT aqui é um erro comum em entrevistas.

-- without DISTINCT, a customer with 3 orders in each year
-- would appear 9 times from the join

EXCEPT como LEFT JOIN / IS NULL

EXCEPT (A, mas não B) é a antijunção. A forma portável é um LEFT JOIN de A para B com base em todas as colunas, mantendo apenas as linhas em que o lado B é NULL (sem correspondência) e, em seguida, aplicando DISTINCT.

Esse padrão LEFT JOIN / IS NULL é um dos truques mais reutilizados em entrevistas de SQL.

SELECT DISTINCT a.customer_id
FROM orders_2023 a
LEFT JOIN orders_2024 b
  ON a.customer_id = b.customer_id
WHERE b.customer_id IS NULL;

EXCEPT com NOT EXISTS

Uma forma igualmente portável de usar EXCEPT emprega NOT EXISTS. Ela pode ser lida como "mantenha cada linha de A para a qual não exista nenhuma linha correspondente de B" e lida robustamente com valores NULL.

Muitos engenheiros preferem NOT EXISTS porque sua intenção é explícita e ele evita a armadilha de NOT IN + NULL.

SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE NOT EXISTS (
  SELECT 1 FROM orders_2024 b
  WHERE b.customer_id = a.customer_id
);

INTERSECT com EXISTS

De forma simétrica, INTERSECT pode ser escrito com EXISTS: mantenha cada linha distinta de A para a qual exista uma linha correspondente de B.

EXISTS interrompe a busca ao encontrar a primeira correspondência, portanto pode ser eficiente e evita a multiplicação de linhas da junção, às vezes eliminando a necessidade de DISTINCT no lado da junção.

SELECT DISTINCT a.customer_id
FROM orders_2023 a
WHERE EXISTS (
  SELECT 1 FROM orders_2024 b
  WHERE b.customer_id = a.customer_id
);

A armadilha de NOT IN com NULL

Uma emulação tentadora de EXCEPT é NOT IN, mas ela é perigosa: se a subconsulta retornar qualquer valor NULL, NOT IN não retornará linha alguma, porque a comparação se torna UNKNOWN.

Essa é uma armadilha muito cobrada em testes. Prefira NOT EXISTS ou LEFT JOIN / IS NULL, que lidam com NULL com segurança.

-- RISKY if orders_2024.customer_id can be NULL:
SELECT DISTINCT customer_id FROM orders_2023
WHERE customer_id NOT IN (
  SELECT customer_id FROM orders_2024
);

Correspondência em várias colunas

Quando a comparação de conjuntos abrange várias colunas, todas elas entram no predicado da junção. Em uma antijunção, também é necessário lidar com a possibilidade de haver valores NULL nessas colunas; é nesse ponto que NOT EXISTS se destaca.

Especifique cada coluna na cláusula ON; deixar uma de fora altera silenciosamente o significado de "linha igual".

SELECT DISTINCT a.id, a.city
FROM a
LEFT JOIN b
  ON a.id = b.id AND a.city = b.city
WHERE b.id IS NULL;

Emulando UNION sem o operador

UNION ALL é apenas concatenação, algo que todo dialeto oferece diretamente. Para emular UNION distinto quando necessário, concatene com UNION ALL dentro de uma subconsulta e envolva o resultado com SELECT DISTINCT ou GROUP BY em todas as colunas.

Isso mostra que UNION é simplesmente UNION ALL mais uma etapa de remoção de duplicatas.

SELECT DISTINCT * FROM (
  SELECT city FROM a
  UNION ALL
  SELECT city FROM b
) combined;

Escolhendo a emulação adequada

Guia de decisão:

  • INTERSECT → EXISTS ou INNER JOIN + DISTINCT.
  • EXCEPT → NOT EXISTS ou LEFT JOIN / IS NULL.
  • Evite NOT IN quando houver possibilidade de NULL.
  • UNION → UNION ALL envolvido em DISTINCT.

EXISTS / NOT EXISTS são as opções mais portáveis e seguras para NULL, o que as torna as respostas mais seguras em entrevistas.

Conectando tudo

Saber traduzir operadores de conjuntos em junções demonstra que você os entende como lógica de conjuntos, e não apenas como sintaxe. A antijunção (LEFT JOIN / IS NULL ou NOT EXISTS) é o padrão de maior valor: ela aparece na emulação de EXCEPT, na localização de registros órfãos e em questões sobre registros ausentes.

Comece por NOT EXISTS para garantir a correção e, depois, mencione a forma com junção ao discutir desempenho.

Verificação rápida

Seu banco de dados não oferece suporte a EXCEPT. Você precisa dos customer_ids presentes em orders_2023 que não estejam em orders_2024, e a coluna pode conter valores NULL.

Recapitulação

Principais conclusões:

  • INTERSECT → INNER JOIN + DISTINCT ou EXISTS.
  • EXCEPT → LEFT JOIN / IS NULL ou NOT EXISTS (antijunção).
  • Adicione DISTINCT para reproduzir o comportamento de remoção de duplicatas dos operadores de conjuntos e controlar a multiplicação de linhas da junção.
  • Evite NOT IN quando houver possibilidade de NULL; prefira NOT EXISTS.
  • UNION = UNION ALL envolvido em DISTINCT.

Perguntas Frequentes

A aula “Emulando operações de conjuntos com junções” é grátis?

Sim — o texto completo de “Emulando operações de conjuntos com junções” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.

O que vou aprender em “Emulando operações de conjuntos com junções”?

Reescreva EXCEPT e INTERSECT em dialetos que não os oferecem. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Interview Prep?

Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Emulando operações de conjuntos com junções”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Interview Prep?

Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. UNION versus UNION ALL
  2. Compatibilidade de quantidade e tipos de colunas
  3. INTERSECT e EXCEPT para comparação
  4. Emulando operações de conjuntos com junções
← Voltar para SQL Interview Prep