Identifizieren, welche Werte NICHT mit einer Tabellenzeile übereinstimmen

10

Ich möchte in der Lage sein, leicht zu überprüfen, welche eindeutigen Bezeichner in einer Tabelle nicht vorhanden sind, von denen, die in einer Abfrage angegeben sind.

Um dies besser zu erklären, würde ich jetzt Folgendes tun, um zu überprüfen, welche IDs der Liste "1, 2, 3, 4" in einer Tabelle nicht vorhanden sind:

  1. SELECT * FROM dbo."TABLE" WHERE "ID" IN ('1','2','3','4')Angenommen, die Tabelle enthält keine Zeile mit der ID 2.
  2. Speichern Sie die Ergebnisse in Excel
  3. Führen Sie ein VLOOKUP für die ursprüngliche Liste aus, das nach jedem Listenwert in der Ergebnisliste sucht.
  4. Jedes VLOOKUP, das zu einem führt, #N/Abefindet sich auf einem Wert, der in der Tabelle nicht vorkommt.

Ich denke, es muss einen besseren Weg geben, dies zu tun. Ich suche im Idealfall so etwas

Zu überprüfende Liste -> Zu überprüfende Tabelle abfragen -> Mitglieder der Liste nicht in Tabelle

NReilingh
quelle
Bitte lassen Sie uns die Version von SQL Server nicht erraten.
Aaron Bertrand
NICHT IN / EXISTIERT? stackoverflow.com/questions/173041/not-in-vs-not-exists
Eric Higgins
Entschuldigung. [bearbeitet] Es ist alt. Das Problem mit NOT IN ist, dass alles andere in der Tabelle zurückgegeben wird ...
NReilingh

Antworten:

14

Verwendung EXCEPT:

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

Siehe SqlFiddle .


Der valuesKonstruktor funktioniert nur unter SQL Server 2008 oder höher. Für 2005 verwenden

SELECT 'value'
UNION SELECT 'value'

wie in dieser SO-Antwort beschrieben .

Remus Rusanu
quelle
Hoppla, hätte spezifizieren sollen. Was ist, wenn ID ein Varchar ist?
NReilingh
1
@NReilingh dann deine DB neu gestalten :) aber es sollte genauso funktionieren wie ich denke
JNK
Ich Incorrect syntax near the keyword 'values'.SELECT * FROM (values ('search string'),('other string')) as T(ID)
bekomme
Ihre Syntax funktioniert in SQL Server 2008r2 einwandfrei. Ich habe Ihren Kommentar eingefügt und er wurde ausgeführt.
JNK
Ich bin auf 2005. Christus.
NReilingh
6

Ich würde eine Tabellenvariable oder eine temporäre Tabelle erstellen, die die IDs enthält, nach denen Sie suchen ... und dann Remus 'Lösung abzüglich des syntaktischen Zuckers von 2008 verwenden:

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
quelle
3

Ich bin jetzt ein paar Jahre weiser (und habe einen neueren SQL Server) als damals, als ich diese Frage gestellt habe. Um das berühmte Fragenabzeichen zu feiern, das ich dafür bekommen habe, würde ich jetzt Folgendes tun. (Ich glaube nicht, dass ich den EXCEPTOperator seitdem jemals benutzt habe .)

Ich würde sagen, dass die folgende LEFT JOINMethode nützlicher ist, als EXCEPTda Sie sie mit anderen Joins erstellen können, ohne einen CTE zu benötigen.

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
quelle