问题
Yesterday I asked a question about ranking students by their points.
[Rank users in mysql by their points ]
I actually solved my problem with the help I've recieved from other question (thanks to everyone who helped me).
Meanwhile I figured out something accidently. If I try to rank my students by their points and if points column was empty (NULL) my query didn't gave an error also it sorted ranks like 1-2-3-4 but all values were NULL
this is the query I've tried
select er.*,
(@rank := if(@points = points,
@rank,
if(@points := points,
@rank + 1,
@rank + 1
)
)
) as ranking
from examresults er cross join
(select @rank := 0, @points := -1) params
order by points desc;
and this is the result.
So I wonder arent NULL values are the same ? isnt this query should gave rank 1 for every user in my database ? why it ranks null values incrementally ?
回答1:
Many people think of NULL
as meaning no value
or non-existent
. Even Wikipedia explains it this way.
Think of it as unknown value
and everything will make more sense.
One cannot compare two unknown values
because, well, they are not known. They are not equal but they are also not different. None of them is greater than the other.
The result of comparison of two unknown values
is also an unknown value
(i.e. NULL
).
回答2:
NULL does not have a value - it is a state of non-existence. So any results based on NULL is non-deterministic. You should EXPLICITLY deal with the possibility of NULL values.
回答3:
You compare @points = points
which results in @points=NULL
.
But any comparison to NULL
results in UNKNOWN
:
value= NULL -> UNKNOWN
value<>NULL -> UNKNOWN
value< NULL -> UNKNOWN
value> NULL -> UNKNOWN
Even NULL=NULL
results in UNKNOWN
.
Of course there are exceptions:
DISTINCT
and GROUP BY
consider NULLs equal.
回答4:
Boolean comparison return true, false, or NULL
, and NULL
is generally treated as false. You can easily modify your query to use NULL
-safe equality:
select er.*,
(@rank := if(@points <=> points,
@rank,
if(@points := points,
@rank + 1,
@rank + 1
)
)
) as ranking
from examresults er cross join
(select @rank := 0, @points := -1) params
order by points desc;
来源:https://stackoverflow.com/questions/34654567/why-null-values-are-not-ranking-same-in-mysql