Ich habe zwei Datenbanken, eine mit dem Inventar und eine mit einer Teilmenge der Datensätze der Primärdatenbank.
Die folgende SQL-Anweisung funktioniert nicht:
SELECT stock.IdStock
,stock.Descr
FROM [Inventory].[dbo].[Stock] stock
WHERE stock.IdStock NOT IN
(SELECT foreignStockId FROM
[Subset].[dbo].[Products])
Das nicht in funktioniert nicht. Das Entfernen des NOT führt zu den richtigen Ergebnissen, dh Produkten, die sich in beiden Datenbanken befinden. Die Verwendung von NOT IN liefert jedoch überhaupt keine Ergebnisse.
Was mache ich falsch, irgendwelche Ideen?
sql
sql-server
Sam
quelle
quelle
Inventory
, die nicht in sindSubset
?Antworten:
SELECT foreignStockId FROM [Subset].[dbo].[Products]
Gibt wahrscheinlich a zurück
NULL
.Eine
NOT IN
Abfrage gibt keine Zeilen zurück, wenn in der WertelisteNULL
s vorhandenNOT IN
sind. Sie können sie explizitIS NOT NULL
wie folgt ausschließen.SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products] WHERE foreignStockId IS NOT NULL)
Oder schreiben Sie
NOT EXISTS
stattdessen mit.SELECT stock.idstock, stock.descr FROM [Inventory].[dbo].[Stock] stock WHERE NOT EXISTS (SELECT * FROM [Subset].[dbo].[Products] p WHERE p.foreignstockid = stock.idstock)
Die Semantik, für die Sie den Ausführungsplan wünschen,
NOT EXISTS
ist oft einfacher, als hier dargestellt .Der Grund für den Unterschied im Verhalten liegt in der dreiwertigen Logik, die in SQL verwendet wird. Prädikate zu bewerten
True
,False
oderUnknown
.Eine
WHERE
Klausel muss ausgewertet werden,True
damit die Zeile zurückgegeben wird. Dies ist jedoch nicht möglich,NOT IN
wenn sieNULL
vorhanden ist, wie unten erläutert.'A' NOT IN ('X','Y',NULL)
ist äquivalent zu'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
True
True
Unknown
True AND True AND Unknown
ausgewertet nachUnknown
den Wahrheitstabellen für drei wertige Logik .Die folgenden Links enthalten zusätzliche Informationen zur Leistung der verschiedenen Optionen.
NOT IN
,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
, oderNOT EXISTS
?NOT IN
vs.NOT EXISTS
vsLEFT JOIN / IS NULL
.: SQL ServerLeft outer join
vs.NOT EXISTS
NOT EXISTS
vs.NOT IN
quelle
Wenn NOT IN nicht funktioniert, können Sie immer versuchen, LEFT JOIN auszuführen . Filtern Sie dann nach WHERE, indem Sie einen der Werte aus der verknüpften Tabelle verwenden, die NULL sind . Vorausgesetzt, der Wert, durch den Sie beigetreten sind, enthält keinen NULL- Wert.
quelle
Sie können auch die Case-Klausel verwenden, um solche Probleme zu lösen
SELECT stock.IdStock ,stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE (Case when stock.IdStock IN (SELECT foreignStockId FROM [Subset].[dbo].[Products]) then 1 else 0 end) = 0
Diese Syntax funktioniert in SQL Server, Oracle und Postgres
quelle
Hinzufügen meiner 2 Cent:
Ich habe SQL Server sogar falsche Ergebnisse Rückkehr zu sehen , wenn die Umstellung auf
not exists
undleft join
- in korrupten Datenbanken . Führen Sie DBCC CHECKTABLE für die beteiligten Tabellen aus, sehen Sie sich auch denNOT IN
Abfrageausführungsplan an und erstellen Sie die beteiligten Indizes neu. Dies sollte helfen.quelle