2013-08-14 31 views
13

Dưới đây là các thiết lập trên PostgreSQL 9.2.4:postgresql KHÔNG iLike khoản không bao gồm chuỗi null giá trị

CREATE TABLE table (
    id integer NOT NULL, 
    some_text text 
); 

Bây giờ chúng ta nhập một kỷ lục, với một chuỗi rỗng hoặc để trống some_text, để khi chúng ta truy vấn:

SELECT * FROM table WHERE some_text IS NULL; 

Tôi nhận lại mục nhập. Càng xa càng tốt.

Tuy nhiên, khi tôi truy vấn:

SELECT * FROM table WHERE some_text NOT ILIKE "%anything%'; 

tôi thấy rằng không có gì được trả lại. Tại sao vậy? Tôi mong đợi một chuỗi rỗng hoặc rỗng là "không giống như anything".

Trả lời

31

Trong SQL, NULL không bằng bất kỳ thứ gì. Cũng không phải là bất bình đẳng với bất cứ điều gì.

Nói cách khác, nếu tôi không nói cho bạn tên đệm của mình, và bạn không cho tôi biết tên đệm của bạn, làm cách nào để biết hai tên đệm của chúng tôi có cùng tên hoặc tên khác không? Chúng ta không thể biết.

Điều này thường đưa mọi người lên trong SQL, vì đó là "tri-value trị giá". Biểu thức có thể là TRUE, FALSE hoặc UNKNOWN. Những người trong chúng ta quen thuộc với đại số boolean biết rằng KHÔNG TRUE là FALSE, và NOT FALSE là TRUE.

Nhưng phần phức tạp là KHÔNG UNKNOWN vẫn KHÔNG BAO GIỜ.

Vì vậy, các giải pháp cho bạn là một trong hai luôn lưu trữ một chuỗi không null trong cột của bạn, nếu không sử dụng một biểu thức để giải thích cho ba giá trị logic:

SELECT * FROM table WHERE some_text NOT ILIKE "%anything%' OR some_text IS NULL; 

Hoặc:

SELECT * FROM table WHERE COALESCE(some_text, '') NOT ILIKE '%anything%'; 

PostgreSQL cũng hỗ trợ một null-safe equality operator:

SELECT * FROM table WHERE some_text IS DISTINCT FROM 'anything'; 

Nhưng thật không may, điều này chỉ hoạt động bình đẳng, không phải cho LIKE/ILIKE với các mẫu và ký tự đại diện.

+1

Tôi thích bạn giải thích với * ẩn số *, nhưng tôi không chắc chắn làm thế nào mà kết nối SQL. Tại sao một 'WHERE null ILIKE '% anything%'' không xác định? – applepie

+1

"Người đàn ông trẻ, trong toán học bạn không hiểu mọi thứ. Bạn chỉ quen với họ." - John von Neumann –

+2

oooh sass. Đó có phải là một câu hỏi khó theo dõi không? – applepie

3

Bạn có thể sử dụng liên hiệp để đạt được mục tiêu của bạn, giống như

SELECT * FROM table WHERE COALESCE(some_text,'') NOT ILIKE "%anything%'; 
Các vấn đề liên quan