Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Elegante Möglichkeit, Zeilen zu löschen, die nicht von einer anderen Tabelle referenziert werden

Es gibt einen berüchtigten Fallstrick für not in . Grundsätzlich ist id not in (1,2,3) ist eine Abkürzung für:

id <> 1 and id <> 2 and id <> 3

Wenn nun Ihre TimeEntries Tabelle enthält eine beliebige Zeile mit einer TaskID von null , der not in übersetzt zu:

ID <> null and ID <> 1 and ID <> 2 AND ...

Das Ergebnis eines Vergleichs mit null ist immer unknown . Da unknown in SQL nicht wahr ist, das where -Klausel filtert alle Zeilen heraus, und am Ende wird nichts gelöscht.

Eine einfache Lösung ist eine zusätzliche where-Klausel in der Unterabfrage:

DELETE FROM Tasks 
WHERE  ID not IN 
       (
       SELECT  TaskID 
       FROM    TimeEntries 
       WHERE   TaskID is not null
       )