O EXCEPT
operador foi introduzido no SQL Server 2005, mas qual é a diferença entre NOT IN
e EXCEPT
?
Faz o mesmo? Gostaria de uma explicação simples com um exemplo.
O EXCEPT
operador foi introduzido no SQL Server 2005, mas qual é a diferença entre NOT IN
e EXCEPT
?
Faz o mesmo? Gostaria de uma explicação simples com um exemplo.
Existem duas diferenças principais entre
EXCEPT
eNOT IN
.EXCETO
EXCEPT
filtra osDISTINCT
valores da tabela à esquerda que não aparecem na tabela à direita. É essencialmente o mesmo que fazer umNOT EXISTS
com umaDISTINCT
cláusula.Ele também espera que as duas tabelas (ou subconjunto de colunas das tabelas) tenham o mesmo número de colunas no lado esquerdo e direito da consulta
Por exemplo, você não pode fazer:
Isso resultaria no erro:
NÃO EM
NOT IN
não filtraDISTINCT
valores e retorna todos os valores da tabela à esquerda que não aparecem na tabela à direita.NOT IN
requer que você compare uma única coluna de uma tabela com uma única coluna de outra tabela ou subconsulta.Por exemplo, se sua subconsulta deveria retornar várias colunas:
Você obteria o seguinte erro:
No entanto, se a tabela à direita contiver a
NULL
nos valores que estão sendo filtrados porNOT IN
, um conjunto de resultados vazio será retornado, potencialmente gerando resultados inesperados.EXEMPLO
Das duas consultas acima,
EXCEPT
retorna 3 linhas de#NewCustomers
, filtrando o 1 e o 3 que correspondem#ExistingCustomers
e o 8 duplicado.NOT IN
não faz essa filtragem distinta e retorna 4 linhas#NewCustomers
com a duplicata 8.Se agora adicionarmos
NULL
a à#ExistingCustomers
tabela, veremos os mesmos resultados retornados porEXCEPT
, porémNOT IN
retornará um conjunto de resultados vazio.Em vez de
NOT IN
, você deve realmente olharNOT EXISTS
e há uma boa comparação entre os dois no blog de Gail Shaw .Uma adição ao excelente comentário de Mark Sinkinson:
Você pode, na verdade, atuar
NOT IN
com mais de uma coluna. Por exemplo, esta é uma consulta * SQLperfeitamente legal :
Que retornará
first_name
elast_name
de todas as pessoas que são funcionários, mas também não são gerentes.*: mas a construção ainda não está implementada no SQL Server.
O NOT IN acima falha porque precisa haver uma correlação entre os predicados na consulta principal e na subconsulta. Se você deixar de fora, obterá uma subconsulta UNCORRELATED.
SELECT * FROM TableA AS nc WHERE ID NOT IN (SELECT ID, Nome FROM TableB AS ec onde nc.ID = ec.ID)
EXCEPT é melhor e manipulará todas as linhas nulas sem usar predicados IS NULL / IS NOT NULL.