Mengapa TIDAK DALAM dengan set yang berisi NULL selalu mengembalikan FALSE / NULL?

21

Saya punya permintaan (untuk Postgres dan Informix) dengan NOT INklausa yang berisi subquery yang dalam beberapa kasus mengembalikan NULLnilai, menyebabkan klausa itu (dan seluruh permintaan) gagal mengembalikan apa pun.

Apa cara terbaik untuk memahami ini? Saya dianggap NULLsebagai sesuatu yang tidak memiliki nilai, dan karena itu tidak mengharapkan permintaan gagal, tetapi jelas itu bukan cara yang benar untuk dipikirkan NULL.

newenglander
sumber

Jawaban:

29

Logika Boolean - atau Tiga logika yang dihargai

  • IN adalah singkatan untuk serangkaian kondisi ATAU
  • x NOT IN (1, 2, NULL) sama dengan NOT (x = 1 OR x = 2 OR x = NULL)
  • ... sama dengan x <> 1 AND x <> 2 AND x <> NULL
  • ... sama dengan true AND true AND unknown**
  • ... = unknown**
  • ... yang hampir sama seperti falsedalam kasus ini karena tidak akan melewati WHEREkondisi **

Sekarang, inilah mengapa orang menggunakan EXISTS+ NOT EXISTSdaripada IN+ NOT IN. Juga lihat Penggunaan logika BUKAN dalam kaitannya dengan indeks untuk lebih

** Catatan: unknownsama dengan falsepada akhir ekspresi dalam suatu WHEREkondisi.
Sementara ekspresi sedang dievaluasi, maka tidak diketahui
Lihat komentar @ kgrittn di bawah ini untuk alasannya

gbn
sumber
10
Bahkan dengan klarifikasi itu secara teknis salah, dan dengan cara yang bisa membakar seseorang. Misalnya, jika Anda menganggapnya x <> NULLsebagai penyelesaian FALSE, Anda akan mengharapkan NOT (x <> NULL)untuk mengevaluasi TRUE, dan ternyata tidak. Keduanya mengevaluasi UNKNOWN. Kuncinya adalah bahwa baris dipilih hanya jika WHEREklausa (jika ada) mengevaluasi ke TRUE- baris dihilangkan jika klausul mengevaluasi salah satu FALSEatau UNKNOWN. Perilaku ini (secara umum, dan untuk NOT INpredikat pada khususnya) diamanatkan oleh standar SQL.
kgrittn
NULL NOT IN (some_subquery)Seharusnya juga tidak mengembalikan baris luar kecuali jika some_subquerytidak mengembalikan baris. Itulah sebabnya rencana eksekusi ketika kedua kolom memiliki Null bisa jauh lebih mahal. Contoh SQL Server
Martin Smith