Postgresql NOT NULL AND <> '' 与 NOT NULL OR <> ''

Postgresql NOT NULL AND <> '' vs NOT NULL OR <> ''

I have read lots about the difference between NOT NULL vs <>''

The best explanation I found for it was in:

https://www.postgresql.org/message-id/AANLkTilEsUTIeUkZCX9Vc14kciFiuvFBRRE-yen4K_Zi@mail.gmail.com which states:

NULL means the question hasn't been answered yet, thus there is no answer, there may be an answer once it is provided so you can't really say the answer is empty. Empty would mean the answer has been given and the answer is empty.

For the table that I am working on, I was trying to filter results for valid postcodes only (postcode is a VARCHAR in this specific table), I tried the following:

SELECT postcode FROM customer_table_1 
WHERE postcode IS NOT NULL OR postcode <> '';

However this gives some blank postcodes in my results. Breaking this down ...

SELECT postcode FROM customer_table_1 
WHERE postcode IS NOT NULL;

gives some blank postcodes whereas

SELECT postcode FROM customer_table_1 
WHERE postcode <>'';

only gives valid postcodes in the result. Therefore the IS NOT NULL part of the query isn't doing what I thought it was.

As part of a more complicated query, I have previously used:

SELECT postcode FROM customer_table_1 
WHERE postcode IS NOT NULL AND postcode <> '';

and have achieved the desired result. However I have always thought it should be

SELECT postcode FROM customer_table_1 
WHERE postcode IS NOT NULL OR postcode <> '';

Because I am looking for all records that have a valid postcode (i.e. are NOT NULL or NOT empty strings) should these not be connected with an OR statement rather than an AND? I'm not looking for postcodes that are both NULL and empty strings, just one or the other.

Apologies if this is a stupid question, using an AND doesn't seem logical to me and I don't want to blindly do something without understanding the process behind the result. I thought I fully understood the difference between NOT NULL and <>'' but as with most things Postgres related, the more I delve into it the more I realize I don't actually know!

当你 or 两个表达式时,结果将是 true 当其中至少一个是 true:

select true or false;
 ?column? 
----------
 t

在您的情况下,每当 postcode is not null 时,结果将是 true。一个空的 postcode is not null 所以它会被返回:

select 
    '' is not null, -- empty is not null
    '' <> '',       -- false
    '' is not null or '' <> '' -- (true or false) is true
 ;
 ?column? | ?column? | ?column? 
----------+----------+----------
 t        | f        | t

了解 De Morgan's Law 布尔逻辑的基础,您会受益匪浅。

在这种情况下,您的情况不是您所表达的:

(NOT NULL) OR (NOT EMPTY)

但实际上是:

NOT (NULL OR EMPTY)

根据 De Morgan 展开实际上变成:

(NOT NULL) AND (NOT EMPTY)

因此 AND 是正确的(实际上是 "logical")运算符。

SELECT postcode FROM customer_table_1 WHERE postcode IS NOT NULL AND postcode != ''

这似乎可以解决问题