Tại sao KHÔNG IN với một tập hợp chứa NULL luôn trả về FALSE / NULL?


21

Tôi đã có một truy vấn (cho Postgres và Informix) với một NOT INmệnh đề chứa một truy vấn con mà trong một số trường hợp trả về NULLcác giá trị, khiến mệnh đề đó (và toàn bộ truy vấn) không trả về bất cứ điều gì.

Cách tốt nhất để hiểu điều này là gì? Tôi đã nghĩ về NULLmột cái gì đó không có giá trị, và do đó không mong đợi truy vấn thất bại, nhưng rõ ràng đó không phải là cách nghĩ chính xác NULL.

Câu trả lời:


29

Logic Boolean - hoặc logic ba giá trị

  • IN là viết tắt cho một loạt các điều kiện OR
  • x NOT IN (1, 2, NULL) giống như NOT (x = 1 OR x = 2 OR x = NULL)
  • ... giống như x <> 1 AND x <> 2 AND x <> NULL
  • ... giống như true AND true AND unknown**
  • ... = unknown**
  • ... gần giống như falsetrong trường hợp này vì nó sẽ không vượt qua WHEREđiều kiện **

Bây giờ, đây là lý do tại sao dân gian sử dụng EXISTS+ NOT EXISTSchứ không phải IN+ NOT IN. Xem thêm Việc sử dụng logic KHÔNG liên quan đến các chỉ mục để biết thêm

** Lưu ý: unknowngiống như falseở cuối biểu thức trong một WHEREđiều kiện.
Trong khi biểu thức đang được đánh giá, thì không rõ
Xem bình luận của @ kgrittn bên dưới để biết lý do


10
Ngay cả với việc làm rõ nó là sai về mặt kỹ thuật, và theo cách có thể đốt cháy một ai đó. Ví dụ: nếu bạn xem x <> NULLlà giải quyết FALSE, bạn sẽ NOT (x <> NULL)đánh giá TRUEvà không. Cả hai đánh giá UNKNOWN. Thủ thuật là một hàng chỉ được chọn nếu WHEREmệnh đề (nếu có) ước tính thành TRUE- một hàng bị bỏ qua nếu mệnh đề ước lượng thành một FALSEhoặc UNKNOWN. Hành vi này (nói chung và đối với NOT INvị từ nói riêng) được quy định bởi tiêu chuẩn SQL.
kgrittn

Cũng NULL NOT IN (some_subquery)không nên trả về hàng ngoài trừ khi some_subquerykhông trả lại bất kỳ hàng nào. Đó là lý do tại sao kế hoạch thực hiện khi cả hai cột đều có khả năng Null có thể đắt hơn đáng kể. Ví dụ về máy chủ SQL
Martin Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.