Identificando quais valores NÃO correspondem a uma linha da tabela

10

Eu gostaria de poder verificar facilmente quais identificadores exclusivos não existem em uma tabela, daqueles fornecidos em uma consulta.

Para explicar melhor, eis o que eu faria agora, para verificar quais IDs da lista "1, 2, 3, 4" não existem em uma tabela:

  1. SELECT * FROM dbo."TABLE" WHERE "ID" IN ('1','2','3','4'), digamos que a tabela não contenha linha com o ID 2.
  2. Despejar os resultados no Excel
  3. Execute um VLOOKUP na lista original que pesquisa cada valor da lista na lista de resultados.
  4. Qualquer VLOOKUP que resulte em #N/Aestá em um valor que não ocorreu na tabela.

Estou pensando que deve haver uma maneira melhor de fazer isso. Estou procurando, idealmente, algo como

Lista para verificar -> Consulta na tabela para verificar -> Membros da lista que não estão na tabela

NReilingh
fonte
Por favor, não nos faça adivinhar a versão do SQL Server?
Aaron Bertrand
NÃO IN / EXISTE? stackoverflow.com/questions/173041/not-in-vs-not-exists #
31513 Eric Higgins
Desculpas. [editado] É velho. O problema com NOT IN é que vai voltar tudo na mesa ...
NReilingh

Respostas:

14

Use EXCEPT:

SELECT * FROM
  (values (1),(2),(3),(4)) as T(ID)
EXCEPT
SELECT ID 
FROM [TABLE];

Consulte SqlFiddle .


O valuesconstrutor funcionará apenas no SQL Server 2008 ou posterior. Para 2005, use

SELECT 'value'
UNION SELECT 'value'

conforme detalhado nesta resposta SO .

Remus Rusanu
fonte
Opa, deveria ter especificado. E se o ID for um varchar?
NReilingh
11
@NReilingh então redesenhar o seu DB :) mas deve funcionar da mesma Acho
JNK
Eu continuo recebendo Incorrect syntax near the keyword 'values'.ao executarSELECT * FROM (values ('search string'),('other string')) as T(ID)
NReilingh
Sua sintaxe funciona bem para mim no SQL Server 2008r2 - colei seu comentário e ele foi executado.
JNK
Estou em 2005. Cristo.
NReilingh
6

Eu criaria uma variável de tabela ou tabela temporária contendo os IDs que você está procurando ... depois usaria a solução de Remus, menos o açúcar sintático de 2008:

declare @t table (ID int)
insert into @t values (1)
insert into @t values (2)
insert into @t values (3)
insert into @t values (4)
insert into @t values (5)

select ID from @t
except
select ID
from [Table];
Michael Fredrickson
fonte
3

Agora estou alguns anos mais sábio (e possuo um SQL Server mais recente) do que quando fiz essa pergunta; portanto, para comemorar o distintivo de Pergunta Famosa que recebi por fazer isso, aqui está o que eu faria agora. (Acho que nunca usei o EXCEPToperador desde então.)

Eu diria que o LEFT JOINmétodo abaixo é mais útil do que EXCEPTdesde que você pode compor com outras junções sem precisar de um CTE.

SELECT v.val
  FROM (VALUES (1), (2), (3), (4), (5)) v (val)
    LEFT JOIN dbo.SomeTable t
      ON t.id = v.val
  WHERE t.id IS NULL;
NReilingh
fonte