Existem basicamente 3 abordagens para que: not exists
, not in
e left join / is null
.
JUNTA ESQUERDA com IS NULL
SELECT l.*
FROM t_left l
LEFT JOIN
t_right r
ON r.value = l.value
WHERE r.value IS NULL
NÃO EM
SELECT l.*
FROM t_left l
WHERE l.value NOT IN
(
SELECT value
FROM t_right r
)
NÃO EXISTE
SELECT l.*
FROM t_left l
WHERE NOT EXISTS
(
SELECT NULL
FROM t_right r
WHERE r.value = l.value
)
Qual é o melhor? A resposta a esta pergunta pode ser melhor dividida em grandes fornecedores específicos de RDBMS. De um modo geral, deve-se evitar o uso select ... where ... in (select...)
quando a magnitude do número de registros na subconsulta for desconhecida. Alguns fornecedores podem limitar o tamanho. O Oracle, por exemplo, tem um limite de 1.000 . A melhor coisa a fazer é tentar os três e mostrar o plano de execução.
Especificamente, forma o PostgreSQL, plano de execução NOT EXISTS
e LEFT JOIN / IS NULL
é o mesmo. Pessoalmente, prefiro a NOT EXISTS
opção porque mostra melhor a intenção. Depois de toda a semântica é que você quiser encontrar registros em um que seus pk não existem em B .
Porém, antigo mas ainda ouro, específico para o PostgreSQL: https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/