Use um
EXISTS
expressão:WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
A diferença
... entre
NOT EXISTS()
(Ⓔ) e NOT IN()
(Ⓘ) é duplo:-
Desempenho
Ⓔ é geralmente mais rápido. Ele para de processar a subconsulta assim que a primeira correspondência for encontrada. O manual:
A subconsulta geralmente só será executada por tempo suficiente para determinar se pelo menos uma linha é retornada, não até a conclusão.
Ⓘ também pode ser otimizado pelo planejador de consultas, mas em menor grau, poisNULL
manuseio torna-o mais complexo.
-
Correção
Se um dos valores resultantes na expressão de subconsulta forNULL
, o resultado de Ⓘ éNULL
, enquanto a lógica comum esperariaTRUE
- e Ⓔ retornaráTRUE
. O manual:
Se todos os resultados por linha forem desiguais ou nulos, com pelo menos um nulo, o resultado deNOT IN
é nulo.
Essencialmente,
(NOT) EXISTS
é a melhor escolha na maioria dos casos. Exemplo
Sua consulta pode ficar assim:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
não junte-se a
votes
na consulta básica. Isso anularia o esforço. Além de
NOT EXISTS
e NOT IN
existem opções de sintaxe adicionais com LEFT JOIN / IS NULL
e EXCEPT
. Ver:- Selecione as linhas que não estão presentes em outra tabela