Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

postgresql NOT ILIKE clause does not include null string values

Tags:

sql

postgresql

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".

like image 862
applepie Avatar asked Aug 14 '13 23:08

applepie


People also ask

Does Postgres treat empty string as NULL?

PostgreSQL databases treat empty strings and NULL as different.

How do you handle NULL values in PostgreSQL?

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.

Is not equal to NULL in PostgreSQL?

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 “=” “!=

Is not equal to string Postgres?

<> 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.


1 Answers

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.

like image 147
Bill Karwin Avatar answered Sep 28 '22 18:09

Bill Karwin