Identifier les valeurs qui ne correspondent PAS à une ligne du tableau

10

Je voudrais pouvoir vérifier facilement quels identifiants uniques n'existent pas dans une table, de ceux fournis dans une requête.

Pour mieux expliquer, voici ce que je ferais maintenant, pour vérifier quels ID de la liste "1, 2, 3, 4" n'existent pas dans un tableau:

  1. SELECT * FROM dbo."TABLE" WHERE "ID" IN ('1','2','3','4'), disons que la table ne contient aucune ligne avec l'ID 2.
  2. Vider les résultats dans Excel
  3. Exécutez une RECHERCHEV sur la liste d'origine qui recherche chaque valeur de liste dans la liste de résultats.
  4. Tout RECHERCHEV qui se traduit par un #N/Aest sur une valeur qui ne s'est pas produite dans la table.

Je pense qu'il doit y avoir une meilleure façon de le faire. Je cherche, idéalement, quelque chose comme

Liste à vérifier -> Requête sur la table à vérifier -> Membres de la liste absents du tableau

NReilingh
la source
Veuillez ne pas nous faire deviner la version de SQL Server?
Aaron Bertrand
Mes excuses. [modifié] C'est vieux. Le problème avec NOT IN, c'est qu'il renverra tout le reste du tableau ...
NReilingh

Réponses:

14

Utilisation EXCEPT:

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

Voir SqlFiddle .


Le valuesconstructeur ne fonctionnera que sur SQL Server 2008 ou version ultérieure. Pour 2005, utilisez

SELECT 'value'
UNION SELECT 'value'

comme détaillé dans cette réponse SO .

Remus Rusanu
la source
Oups, aurait dû préciser. Que faire si l'ID est un varchar?
NReilingh
1
@NReilingh a ensuite repensé votre base de données :) mais cela devrait fonctionner de la même façon je pense
JNK
Je continue à Incorrect syntax near the keyword 'values'.courirSELECT * FROM (values ('search string'),('other string')) as T(ID)
NReilingh
Votre syntaxe fonctionne bien pour moi dans SQL Server 2008r2 - j'ai collé votre commentaire et il s'est exécuté.
JNK
Je suis en 2005. Christ.
NReilingh
6

Je construirais une variable de table ou une table temporaire contenant les ID que vous recherchez ... puis j'utiliserais la solution de Remus, moins le sucre syntaxique 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
la source
3

Je suis maintenant deux ans plus sage (et j'ai un SQL Server plus récent) que lorsque j'ai posé cette question, donc pour célébrer le badge Famous Question que j'ai obtenu pour poser cette question, voici ce que je ferais maintenant. (Je ne pense pas avoir utilisé l' EXCEPTopérateur depuis.)

Je dirais que la LEFT JOINméthode ci-dessous est plus utile que EXCEPTpuisque vous pouvez la composer avec d'autres jointures sans avoir besoin d'un 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
la source