SQL NULL: tricky equality

Don't get confused with NULL in SQL!


Especially when creating a SQL quary from the code, to make the life easier we are using constructions like this:

SELECT * FROM test WHERE 1=1

Then we can easily add a new condition just joined with AND (or OR):

SELECT * FROM test WHERE 1=1 AND ...

and it will be working perfectly fine.

Working with constans can't bring any problem, but it's getting tricky when we're working with variables (columns) like this:

SELECT * FROM test WHERE num=num

The problem is the special value NULL.

Why do we actually need num = num instead of 1 = 1? Well it could be handy when we have a condition inside the query:

SELECT * FROM test WHERE val =  IF(num > 2, 3, val)

By this query we say: give me all the data in the test table where the value of the val column equals 3, in case that value of the num column is greater then 2, otherwise we don't care of the value of the val at all.

Comment: the control flow function IF is RDBMS-related (IF is available in MySQL).

In case when the val column contains NULL values, we can get unexpected behaviour (unexpected for us, but logic as we will see next).

Working with the NULL values

Let's consider a simple table:

CREATE TABLE test (num INT, str VARCHAR(100), str2 VARCHAR(100));

with different values containg NULL values:

INSERT INTO test VALUES (1, 'abc', 'abc'), (2, NULL, NULL), (NULL, '3', NULL), (NULL, NULL, NULL);

The table looks like following:

num
str
str2
 1  abc  abc
 2 NULL NULL
 NULL  3 NULL
 NULL
NULL NULL

Executing this query:

SELECT * FROM test WHERE num = num;

will return

num
str
str2
 1 abc
 abc
 2  NULL  NULL

But it's very suspicious, because we have added four not two rows.

NULL values can't be compared by the = equality operator. The same behaviour we can see in this example:

SELECT * FROM test WHERE str = str2;
num
str
str2
 1 abc
 abc

Instead of = operator we need to use IS operator:

SELECT * FROM test WHERE num IS num;

will return the whole table.

SELECT * FROM test WHERE str IS str2;
num
str
str2
 1  abc  abc
 2 NULL NULL
 NULL
NULL NULL

 

NULL is an unknown value. As NULL != NULL, we can't do num = NULL nor num != NULL to get the expected results.

Always use IS (IS NOT) operators while working with NULL values.