Perché NOT IN con un set contenente NULL restituisce sempre FALSE / NULL?


21

Ho avuto una query (per Postgres e Informix) con una NOT INclausola contenente una sottoquery che in alcuni casi restituiva NULLvalori, facendo sì che quella clausola (e l'intera query) non restituissero nulla.

Qual è il modo migliore per capirlo? Ho pensato NULLa qualcosa senza valore e quindi non mi aspettavo che la query fallisse, ma ovviamente non è questo il modo corretto di pensare NULL.

Risposte:


29

Logica booleana - o logica a tre valori

  • IN è una scorciatoia per una serie di condizioni OR
  • x NOT IN (1, 2, NULL) equivale a NOT (x = 1 OR x = 2 OR x = NULL)
  • ... equivale a x <> 1 AND x <> 2 AND x <> NULL
  • ... è uguale a true AND true AND unknown**
  • ... = unknown**
  • ... che è quasi lo stesso falsedi questo caso in quanto non passerà la WHEREcondizione **

Ora, questo è il motivo per cui la gente usa EXISTS+ NOT EXISTSanziché IN+ NOT IN. Vedi anche L'uso della logica NOT in relazione agli indici per ulteriori informazioni

** Nota: unknownè uguale falsealla fine di un'espressione in una WHEREcondizione.
Mentre l'espressione viene valutata, allora non è noto
Vedi il commento di @ kgrittn qui sotto per il perché


10
Anche con il chiarimento è tecnicamente sbagliato e in un modo che potrebbe bruciare qualcuno. Ad esempio, se ritieni x <> NULLche si stia risolvendo FALSE, ti aspetteresti NOT (x <> NULL)di valutarlo TRUEe non lo fa. Entrambi valutano UNKNOWN. Il trucco è che una riga viene selezionata solo se la WHEREclausola (se presente) restituisce TRUE- una riga viene omessa se la clausola restituisce FALSEo UNKNOWN. Questo comportamento (in generale e per il NOT INpredicato in particolare) è obbligatorio per lo standard SQL.
kgrittn,

Inoltre NULL NOT IN (some_subquery), non deve restituire la riga esterna, tranne se some_subquerynon restituisce alcuna riga. Questo è il motivo per cui il piano di esecuzione quando entrambe le colonne sono in grado di null può essere considerevolmente più costoso. Esempio di SQL Server
Martin Smith,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.