Dlaczego NOT IN z zestawem zawierającym NULL zawsze zwraca FALSE / NULL?


21

Miałem zapytanie (dla Postgres i Informix) z NOT INklauzulą ​​zawierającą podzapytanie, które w niektórych przypadkach zwracało NULLwartości, powodując, że ta klauzula (i całe zapytanie) niczego nie zwróciła.

Jak najlepiej to zrozumieć? Myślałem o NULLczymś bez wartości i dlatego nie spodziewałem się, że zapytanie zakończy się niepowodzeniem, ale oczywiście nie jest to właściwy sposób myślenia NULL.

Odpowiedzi:


29

Logika boolowska - lub logika trójwartościowa

  • IN jest skrótem dla szeregu warunków OR
  • x NOT IN (1, 2, NULL) jest taki sam jak NOT (x = 1 OR x = 2 OR x = NULL)
  • ... jest taki sam jak x <> 1 AND x <> 2 AND x <> NULL
  • ... jest taki sam jak true AND true AND unknown**
  • ... = unknown**
  • ... co jest prawie takie samo jak falsew tym przypadku, ponieważ nie spełni WHEREwarunku **

Teraz, to dlaczego użycie ludowa EXISTS+ NOT EXISTSzamiast IN+ NOT IN. Zobacz także Korzystanie z logiki NOT w stosunku do indeksów, aby uzyskać więcej

** Uwaga: unknownjest taki sam jak falsena końcu wyrażenia w WHEREwarunku.
Podczas oceny wyrażenia nie jest znane.
Zobacz komentarz @ kgrittn poniżej, aby dowiedzieć się, dlaczego


10
Nawet z wyjaśnieniem jest to technicznie niepoprawne iw sposób, który mógłby kogoś poparzyć. Na przykład, jeśli zobaczyć x <> NULLjak postanawiając FALSE, można się spodziewać NOT (x <> NULL), aby ocenić na TRUE, a tak nie jest. Obaj oceniają na UNKNOWN. Sztuczka polega na tym, że wiersz jest wybierany tylko wtedy, gdy WHEREklauzula (jeśli jest obecna) ocenia na TRUE- wiersz jest pomijany, jeśli klauzula ocenia na jeden FALSElub UNKNOWN. To zachowanie (ogólnie, a NOT INzwłaszcza predykat) jest wymagane przez standard SQL.
kgrittn

Nie NULL NOT IN (some_subquery)powinien również zwracać zewnętrznego wiersza, chyba że some_subquerynie zwróci żadnych wierszy. Dlatego plan wykonania, gdy obie kolumny mają wartość Null, może być znacznie droższy. Przykład serwera SQL
Martin Smith,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.