0Pricing
SQL Academy · Aula

Antijunções e semijunções (NOT EXISTS)

Encontre “linhas em A sem correspondência em B” (antijunção) e “linhas em A com pelo menos uma correspondência em B” (semijunção) usando EXISTS/NOT EXISTS.

Antijunções e semijunções (NOT EXISTS) é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 3 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 Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.

Semi-join: "tem pelo menos uma correspondência"

Retorne as linhas de A que tenham pelo menos uma linha correspondente em B — mas somente as colunas de A. O SQL implementa semi-joins por meio de EXISTS ou IN.

Semi-join com EXISTS

Usuários que fizeram pelo menos um pedido:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

Semi-join com IN

O mesmo resultado, com um estilo diferente:

SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);

Por que EXISTS geralmente vence

EXISTS interrompe a busca assim que encontra a primeira correspondência para cada linha externa. IN pode materializar todo o conjunto interno. Os planejadores modernos frequentemente otimizam ambos para o mesmo plano, mas EXISTS é a opção mais segura para conjuntos internos enormes.

Anti-join: "não tem correspondência"

Usuários que NEVER fizeram um pedido — três formas idiomáticas:

-- NOT EXISTS (preferred):
SELECT u.* FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

-- LEFT JOIN ... IS NULL:
SELECT u.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;

-- NOT IN (risky with NULLs):
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);

Por que NOT IN é arriscado

Se a subconsulta interna contiver NULL, NOT IN retornará NULL — e WHERE descartará as linhas cujo predicado seja NULL. Resultado: zero linhas. NOT EXISTS não tem esse problema.

Otimização pelo planejador

O PostgreSQL moderno reconhece EXISTS e NOT EXISTS como padrões de semi-join/anti-join e pode executá-los com hash joins:

EXPLAIN ANALYZE
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
-- → Hash Anti Join

Anti-joins com várias colunas

Use chaves compostas:

SELECT * FROM order_items oi
WHERE NOT EXISTS (
  SELECT 1 FROM shipments s
  WHERE s.order_id = oi.order_id
    AND s.line_no  = oi.line_no
);

Semi-join com EXISTS + predicado adicional

Adicione filtros à subconsulta interna:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.user_id = u.id
    AND o.status = 'paid'
    AND o.created_at >= NOW() - INTERVAL '30 days'
);

Crie um índice na coluna de correlação

Tanto em EXISTS quanto em NOT EXISTS, a subconsulta interna filtra pela chave da linha externa. Sem um índice nessa chave, você terá uma varredura para cada linha externa:

CREATE INDEX orders_user_id_idx ON orders(user_id);

Quando usar LEFT JOIN ... IS NULL

Para painéis que também precisam das colunas do lado sem correspondência, o estilo LEFT JOIN se encaixa naturalmente. Para a semântica pura de anti-join, NOT EXISTS é mais claro.

Além do SQL: filtros de Bloom

Para anti-joins enormes, um pré-filtro de Bloom pode ajudar. O PostgreSQL oferece índices bloom por meio da extensão bloom.

Recapitulação

Semi-join = "tem correspondência"; anti-join = "não tem correspondência".

  • EXISTS para semi-join
  • NOT EXISTS para anti-join (seguro para NULL)
  • Crie um índice na coluna de correlação
  • Evite NOT IN, a menos que a consulta interna não possa conter NULL

Verificação rápida

Você quer usuários que NEVER fizeram um pedido. Qual é o SQL mais seguro e idiomático?

Perguntas Frequentes

A aula “Antijunções e semijunções (NOT EXISTS)” é grátis?

Sim — o texto completo de “Antijunções e semijunções (NOT EXISTS)” é 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 Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.

O que vou aprender em “Antijunções e semijunções (NOT EXISTS)”?

Encontre “linhas em A sem correspondência em B” (antijunção) e “linhas em A com pelo menos uma correspondência em B” (semijunção) usando EXISTS/NOT EXISTS. Você pratica SQL Academy 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 Academy?

Nenhuma experiência prévia é necessária. SQL Academy 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 3 de 4.

Quanto tempo leva a aula “Antijunções e semijunções (NOT EXISTS)”?

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 Academy?

Sim. Cada aula de SQL Academy 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. Junções cruzadas e produtos cartesianos
  2. Junções laterais (LATERAL JOIN)
  3. Antijunções e semijunções (NOT EXISTS)
  4. Ajuste de desempenho de junções entre várias tabelas
← Voltar para SQL Academy