2013-07-16 100 views
17

tôi đã nhầm lẫn đằng sau những lập luận trong các cách sau:Tại sao PostgreSQL không trả về giá trị null khi điều kiện là <> true

SELECT * FROM table WHERE avalue is null 

Returns x số hàng nơi 'Avalue' là null

SELECT * FROM table WHERE avalue <> true 

không trả lại các hàng có 'avalue' là không.

lập luận của tôi (mà dường như là không chính xác) là như null là một giá trị duy nhất (nó không phải là thậm chí bằng null) có nghĩa là nó sẽ hiển thị trong kết quả thiết lập như nó không phải là bằng true một trong hai.

Tôi đoán bạn có thể lập luận rằng bằng cách nói column <> value bạn ngụ ý rằng cột có giá trị do đó bỏ qua các giá trị null hoàn toàn.

Lý do đằng sau điều này là gì và điều này có giống nhau trong SQL DB thông thường khác không?

Lý do của tôi (giả định) cho tôi biết điều này phản trực giác và tôi muốn tìm hiểu lý do.

+8

[Ba giá trị Logic] (http://en.wikipedia.org/wiki/Three-valued_logic). Bạn giả sử rằng các câu trả lời duy nhất có thể cho '<>' là 'true' hoặc' false' - trong khi trong SQL, có tùy chọn 'unknown'. Đây là tiêu chuẩn. (Nhạy cảm, MySQL liên kết 'UNKNOWN' và' NULL' để ở đó, các kết quả có thể là 'TRUE',' FALSE' và 'NULL') –

+1

SQL Server thực hiện theo cách tương tự. – Fanda

+0

Như Damien đang nói ... Điều này thường được gọi là ba giá trị logic. – Kuberchaun

Trả lời

27

Mỗi nửa chừng RDBMS cũng giống như vậy, vì đó là chính xác.
Tôi trích dẫn the Postgres manual here:

toán tử so sánh thông thường năng suất null (nghĩa "không rõ"), không đúng hay sai, khi một trong hai đầu vào là null. Ví dụ: 7 = NULL sản lượng không, cũng như 7 <> NULL.Khi hành vi này là không phù hợp, sử dụng IS [ NOT ] DISTINCT FROM cấu trúc:

expression IS DISTINCT FROM expression 
expression IS NOT DISTINCT FROM expression 

Lưu ý rằng các biểu thức thực hiện chậm hơn một chút so với đơn giản expression <> expression so sánh.

Đối với boolean giá trị cũng có đơn giản hơn IS NOT [TRUE | FALSE].
Để có được những gì bạn mong đợi trong truy vấn thứ hai của bạn, hãy viết:

SELECT * FROM table WHERE avalue IS NOT TRUE;

SQL Fiddle.

+0

IMHO, đây là logic sai lầm và không phải là 'chính xác'. Nếu tôi so sánh 7 với NULL, câu trả lời sẽ không được biết, câu trả lời phải là sai. Đây là logic uốn SQL. Dù sao, nhờ có câu trả lời tuyệt vời, 'IS DISTINCT FROM' đã được cứu trong ngày. – sandre89

+1

@ sandre89 Vấn đề là bạn không thể xác định toán tử kết hợp hoặc so sánh NULL (hoặc "không xác định") với bất kỳ thứ gì khác. Kết quả sẽ là gì đối với '7> NULL' hoặc' 7 NULL' không có ý nghĩa, và kết quả là do đó không rõ (được biểu diễn là' NULL'). –

+0

@WizardofOgz Tôi đồng ý rằng 7> NULL không có ý nghĩa. Nhưng 7 <> NULL là đúng và không có cách nào xung quanh nó: nó khác nhau. Cùng một cách 7 = NULL nên sai. – sandre89

2

Điều đó là bình thường. SQL Server thực hiện nó theo cùng một cách. Trong SQL Server, bạn có thể sử dụng

SELECT * FROM table WHERE ISNULL(avalue, 0) <> 1 

Đối postgresql tương đương xem này: What is the PostgreSQL equivalent for ISNULL()

Cân nhắc sử dụng đặc điểm kỹ thuật cột NOT NULL với giá trị mặc định, nếu nó làm cho tinh thần.

EDIT:

Tôi nghĩ rằng đó là logic. NULL không phải là một giá trị, do đó, nó được loại trừ khỏi tìm kiếm - bạn phải xác định rõ ràng. Nếu các nhà thiết kế SQL quyết định đi theo cách thứ hai (bao gồm tự động null), thì bạn sẽ gặp nhiều rắc rối hơn nếu bạn cần nhận ra không có giá trị

4

This link cung cấp thông tin chi tiết hữu ích. Có hiệu quả như @Damien_The_Unbeliever chỉ ra, nó sử dụng logic ba giá trị và dường như (theo bài báo) chủ đề của cuộc tranh luận.

Một vài liên kết tốt khác có thể được tìm thấy herehere.

Tôi nghĩ rằng nó sẽ giảm xuống không phải là một giá trị, nhưng một người giữ chỗ cho một giá trị và một quyết định phải được thực hiện và điều này là ... vì vậy NULL không bằng bất kỳ giá trị nào vì nó không một giá trị và thậm chí sẽ không bằng bất kỳ giá trị nào .... nếu điều đó có ý nghĩa.

+0

Bài viết tại cuộc nói chuyện đơn giản có lỗi với bảng AND. Nó nói rằng "false AND unknown is unknown" khi nó phải là "false AND unknown is false". Tương tự với "không xác định và sai", nó phải là "sai". Điều này được thảo luận trong các ý kiến ​​của bài viết nhưng bài viết chưa được cập nhật. – mangoDrunk