Here's the setup on Postgresql 9.2.4:
CREATE TABLE table ( id integer NOT NULL, some_text text );
Now we enter one record, with a null or empty string for some_text
, so that when we query:
SELECT * FROM table WHERE some_text IS NULL;
I get the entry back. So far so good.
However, when I query:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%';
I find that nothing was returned. Why is that? I expect a null or empty string to be "not like anything
".
PostgreSQL databases treat empty strings and NULL as different.
nullif also used with the coalesce function to handle the null values. PostgreSQL nullif function returns a null value if provided expressions are equal. If two expressions provided are equal, then it provides a null value; as a result, otherwise, it will return the first expression as a result.
In PostgreSQL, NULL means no value. In other words, the NULL column does not have any value. It does not equal 0, empty string, or spaces. The NULL value cannot be tested using any equality operator like “=” “!=
<> or != (Not equal): It will return the true value when the given string is not equal to each other. = (Equal): It will return the true value when the two string are same also the type of the string is same.
In SQL, NULL is not equal to anything. Nor is it unequal to anything.
In other words, if I don't tell you my middle name, and you don't tell me your middle name, how can we know if our two middle names are the same name or different names? We can't know.
This often trips people up in SQL, because it's "tri-value logic." An expression can be TRUE, FALSE, or UNKNOWN. Those of us familiar with boolean algebra know that NOT TRUE is FALSE, and NOT FALSE is TRUE.
But the tricky part is that NOT UNKNOWN is still UNKNOWN.
So the solution for you is either always store a non-null string in your column, or else use an expression to account for tri-value logic:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%' OR some_text IS NULL;
Or:
SELECT * FROM table WHERE COALESCE(some_text, '') NOT ILIKE '%anything%';
PostgreSQL also supports a null-safe equality operator:
SELECT * FROM table WHERE some_text IS DISTINCT FROM 'anything';
But unfortunately, this works only for equality, not for LIKE/ILIKE with patterns and wildcards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With