Just a little adjustment for those who come later:
The equality operator generates an unknown value when there is a null
and the unknown value is treated a false
.
Not (unknown)
is still unknown
.
In the example below I'll ask if a couple (a1, b1)
is equal to (a2, b2)
.
Note that each column has 3 values: 0
, 1
and NULL
.
DECLARE @t table (a1 bit, a2 bit, b1 bit, b2 bit)
Insert into @t (a1 , a2, b1, b2)
values( 0 , 0 , 0 , NULL )
select
a1,a2,b1,b2,
case when (
(a1=a2 or (a1 is null and a2 is null))
and (b1=b2 or (b1 is null and b2 is null))
)
then
'Equal'
end,
case when not (
(a1=a2 or (a1 is null and a2 is null))
and (b1=b2 or (b1 is null and b2 is null))
)
then
'Not Equal'
end,
case when (
(a1<>a2 or (a1 is null and a2 is not null) or (a1 is not null and a2 is null))
or (b1<>b2 or (b1 is null and b2 is not null) or (b1 is not null and b2 is null))
)
then
'Different'
end
from @t
Note that here, the results we expect are:
- Equal to be null
- Not equal to be not
equal
- Different to be different
But instead, we get another result
- Equal is null - what we expected.
- Not Equal is null ???
- Different is different - what we expected.
NOT (...)
is bad practice when the code can be easily negated to be in the affirmative or de Morgan'd due to readability. Like, you shouldn't write code likeIF (NOT(A)) THEN [x] ELSE [y] END
when you could just writeIF (A) THEN [y] ELSE [x] END
– Elaskanator