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, poisNULLmanuseio 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