To add a bit of twist to this, try this out:
select (case when null = null then 1 else 0 end) from dual
This returns 0
too. Null is not even equal to itself.
But then what does this return?
select (case when null <> null then 1 else 0 end) from dual
This returns 0
again! Oh holy... It is not even not equal to itself, while it is not equal to itself... Quite a situation to grasp without getting insane...
Why to keep this all in mind? - one might ask
One example is indexing: in Oracle, indexes don't work the way one would expect them to work on NULL
values where a column permits the use of that value. This means that given an index, if all the values (fields, functions on fields, etc) of a row that are included in the index are all NULL
, that row won't be indexed in that given index. So this means that an index, that has only one value indexed (for example, a field directly), a null value would mean that row not to be included in the index.
To overcome this
- it might be advisable to add an index with a distinct, exact value semantically representing the
NULL
meaning, like NVL(mynullcol,-1)
on a column only containing positive integers to be able to query them quickly.
- or you could add a constant value to form a "semi-multivalue" index, that indexes all rows, where one can be null, as the other is a constant. (
create index idx_myindex on table(column_with_nulls,1);
)
(This question and this article detail this subject in a bit more depth)
Another example is ordering...
select (case when null < null then 1 else 0 end) from dual;
select (case when null > null then 1 else 0 end) from dual;
Both 0
. This is OK... We expected this by now... And what about this?
select (case when 'Abc' > null then 1 else 0 end) from dual;
select (case when null > 'Abc' then 1 else 0 end) from dual;
Uh-oh... Both 0
again. This might be an issue - how is ordering going to work?
select col_1 from
(select null as col_1 from dual)
union all (select 'Abc' as col_1 from dual)
union all (select null as col_1 from dual)
union all (select null as col_1 from dual)
order by col_1
This however consistently returns:
Abc
null
null
null
Using ... order by col_1 DESC
returns:
null
null
null
Abc
So from this, on an empirical basis, it does seem that 'Abc' < null
... However, as per the valuable comment of @ypercube:
the sort order can be set with the NULLS LAST
and NULLS FIRST
modifiers (at least in Oracle).
What you observe is the default sort order when the ORDER BY has no modifier
NULL
is a twisted business, it is wise to steer away from it if it is possible... (And this is not only true for SQL, but for certain situations in OOP languages too.)