Why is this query returning 0 rows?
select t.f1, t.f2
from (select null f1, \'a\' f2 from dual) t
where t.f1<>t.f2;
This is a distill
The concept of NULL
is a common source of confusion for newcomers to SQL, who often think that NULL
is treated as the other values.
This is not the case. Conceptually, NULL
means "a missing unknown value" and therefore it is treated very differently.
What you are seeing is pretty easy to explain. Consider the following example:
CREATE TABLE mytb (id int, value int);
INSERT INTO mytb VALUES (1, 100);
INSERT INTO mytb VALUES (2, 200);
INSERT INTO mytb VALUES (3, NULL);
INSERT INTO mytb VALUES (4, 400);
The above means that for the row with id = 3
, the value is "unknown". It could be 300
, or it could be 100
, or anything else.
Therefore when you request the following:
SELECT * FROM mytb WHERE value <> 100;
+------+-------+
| id | value |
+------+-------+
| 2 | 200 |
| 4 | 400 |
+------+-------+
2 rows in set (0.00 sec)
The row with id = 3
is not returned, because NULL <> 100
returns "unknown". We don't know if row id = 3
has a value of 100, so the expression does not return true
. I doesn't return false
either. It returns "unknown" (NULL
).
The condition of the WHERE
clause can only be satisfied when the expression is true
. When you compare something to NULL
, the expression can never be true. It will be "unknown".