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 distilled version of a complex query I have. I want to compare two tables containing one-to-one related data and I want to select those rows that contain different values for certain fields. But also there can be the case where one row is missing in one of the tables. The LEFT JOIN correctly returns null values for these rows, but then, the WHERE clause is incorrectly (or unexpectedly) filtering these rows out.
Why -in this case- 'null' IS NOT DIFFERENT to any not null value (like 'a') ?
What is driving me crazy is that this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t;
returns 1 row (as I expected) but this
select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1=t.f2;
returns 0 rows !! So null is not equal to 'a' and null is not different to 'a' !!
Please... Can anybody explain this?
SQL NULL does not work the way you would like it to work: http://en.wikipedia.org/wiki/Sql_null
In short,
NULL = NULL
is not true.NULL <> NULL
is not true.NULL <> 1
is not true. And so forth.Try to do this query:
It returns 0 rows. That's because to compare a value with null you have to do
IS NULL
orIS NOT NULL
, otherwise it will return false.The concept of
NULL
is a common source of confusion for newcomers to SQL, who often think thatNULL
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:
The above means that for the row with
id = 3
, the value is "unknown". It could be300
, or it could be100
, or anything else.Therefore when you request the following:
The row with
id = 3
is not returned, becauseNULL <> 100
returns "unknown". We don't know if rowid = 3
has a value of 100, so the expression does not returntrue
. I doesn't returnfalse
either. It returns "unknown" (NULL
).The condition of the
WHERE
clause can only be satisfied when the expression istrue
. When you compare something toNULL
, the expression can never be true. It will be "unknown".NULL value is nothing, it can't be equal or not equal to something. If you want to check if your value is null - use "IS NULL" statement:
If you want to check if your values are equal or not equal - you can use COALESCE function on nullable columns:
Exactly.
NULL
represents an unknown value, not any specific value (it is not the same asNULL
in C, ornil
in Ruby, etc.) In SQL, if you compare something to the unknown value, the result is also unknown. And you will not get the rows whereWHERE
condition is unknown.Try this:
and you will see
NULL
as result.Try this:
and no rows will come out, even if the table
t
is huge.If you really need what you said you wanted (and I am not advocating this), you can do something like this: