Skip to Main Content
  • Questions
  • How to use the null column in where condition

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Harikumar.

Asked: January 10, 2017 - 6:44 am UTC

Last updated: January 10, 2017 - 5:22 pm UTC

Version: Release 9.0.1.3.0

Viewed 1000+ times

You Asked

Hi Tom,

I have a situation were for some record one column is having a value and for few records the column value is null.
how do i select the record for this case.


For eg

select segment1,segment2 from abc
nvl(segment2,'')=nvl(segment2,'')

Above query is giving no record,but when is use IS NULL condition i am able to see the record. i want to derive all the records which are having segment 2 is null and segment2 having a value.

Thanks
Hari

and Chris said...

So you want the rows where both columns have the same value or both are null?

If so, the problem with your nvl is that the empty string "''" is also null! So when if you have rows where both are null, you effectively have null = null. Which of course, your query won't return.

To overcome this, pass an "impossible" value as the second argument to nvl:

drop table t purge;
create table t (
  x int, 
  y int
);

insert into t values (1, 1);
insert into t values (1, 2);
insert into t values (null, null);
insert into t values (null, 1);
commit;

set null <null>
select * from t
where  nvl(x, -99) = nvl(y, -99);

X       Y       
1       1       
<null>  <null>  


Or you could write it out longhand, explicitly checking both for null:

select * from t
where  x = y or (x is null and y is null);

X       Y       
1       1       
<null>  <null>  


This avoids possible issues where the value you use in nvl turns out to be a valid!

insert into t values (null, -99);

select * from t
where  nvl(x, -99) = nvl(y, -99);

X       Y       
1       1       
<null>  <null>  
<null>  -99    

select * from t
where  x = y or (x is null and y is null);

X       Y       
1       1       
<null>  <null>  



Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Can maybe use arithmetics?

Christian COMMARMOND, January 10, 2017 - 1:16 pm UTC

Hi,

if segment1 and segment2 are numbers, then arithmetics may work:

select x,y 
from abc
where nvl(x-y,0) = 0;


Will returns lines for which x = y (because x-y=0)
OR where x is NULL OR y IS NULL because NULL-1 is NULL so the nvl will return 0.

So this line is like testing:
x=y OR x IS NULL OR y IS NULL

and probably faster.

I advise to put a comment in your code...

Maybe it helps.

Christian
Chris Saxon
January 10, 2017 - 5:22 pm UTC

That doesn't work. null - 1 = null. So you'll get rows where one value is null and the other isn't:

create table t (
  x int, 
  y int
);

insert into t values (1, 1);
insert into t values (1, 2);
insert into t values (null, null);
insert into t values (null, 1);
commit;

set null <null>
select * from t
where  nvl(x-y, 0) = 0;

X       Y       
1       1       
<null>  <null>  
<null>  1