Bạn phải phân biệt hai tình huống: bạn so sánh một CỘT với NULL hoặc bạn so sánh toàn bộ ROW (RECORD) với NULL.
Hãy xem xét các truy vấn sau:
SELECT
id,
txt,
txt IS NULL AS txt_is_null,
NOT txt IS NULL AS not_txt_is_null,
txt IS NOT NULL AS txt_is_not_null
FROM
(VALUES
(1::integer, NULL::text)
)
AS x(id, txt) ;
Bạn nhận được điều này:
+----+-----+-------------+-----------------+-----------------+
| id | txt | txt_is_null | not_txt_is_null | txt_is_not_null |
+----+-----+-------------+-----------------+-----------------+
| 1 | | t | f | f |
+----+-----+-------------+-----------------+-----------------+
Đây là, tôi đoán, những gì bạn và tôi sẽ mong đợi. Bạn đang kiểm tra một CỘT với NULL và bạn nhận được "txt IS NOT NULL" và "KHÔNG txt IS NULL" là tương đương.
Tuy nhiên, nếu bạn thực hiện một kiểm tra khác:
SELECT
id,
txt,
x IS NULL AS x_is_null,
NOT x IS NULL AS not_x_is_null,
x IS NOT NULL AS x_is_not_null
FROM
(VALUES
(1, NULL)
)
AS x(id, txt) ;
Sau đó, bạn nhận được
+----+-----+-----------+---------------+---------------+
| id | txt | x_is_null | not_x_is_null | x_is_not_null |
+----+-----+-----------+---------------+---------------+
| 1 | | f | t | f |
+----+-----+-----------+---------------+---------------+
Điều này có thể gây ngạc nhiên. Một điều có vẻ hợp lý (x IS NULL) và (KHÔNG x IS NULL) trái ngược với nhau. Một điều khác (thực tế là cả "x IS NULL" hay "x IS NOT NULL" đều không đúng sự thật), trông thật kỳ lạ.
Tuy nhiên, đây là những gì tài liệu PostgreQuery nói rằng sẽ xảy ra:
Nếu biểu thức có giá trị hàng, thì IS NULL là đúng khi chính biểu thức hàng là null hoặc khi tất cả các trường của hàng là null, trong khi IS KHÔNG NULL là đúng khi chính biểu thức hàng là null và tất cả các trường của hàng là không null. Do hành vi này, IS NULL và IS NOT NULL không luôn trả về kết quả nghịch đảo cho các biểu thức có giá trị hàng; đặc biệt, một biểu thức có giá trị hàng chứa cả trường null và không null sẽ trả về false cho cả hai bài kiểm tra. Trong một số trường hợp, có thể tốt hơn là viết hàng IS DISTINCT TỪ NULL hoặc hàng KHÔNG PHẢI DISTINCT TỪ NULL, điều này sẽ đơn giản kiểm tra xem giá trị hàng tổng thể có null hay không mà không có bất kỳ kiểm tra bổ sung nào trên các trường hàng.
Tôi phải thú nhận rằng tôi đã không nghĩ rằng mình đã từng sử dụng một so sánh có giá trị so với null, nhưng tôi đoán rằng nếu khả năng là có, có thể có một số trường hợp sử dụng cho nó. Tôi không nghĩ là phổ biến, dù sao đi nữa.