MySQL之谜:空值与非空字符串没有区别

tat*_*ato 3 mysql null

为什么此查询返回0行?

select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1<>t.f2;
Run Code Online (Sandbox Code Playgroud)

这是我所拥有的复杂查询的简化版本.我想比较两个包含一对一相关数据的表,并且我想选择那些包含某些字段的不同值的行.但也可能存在其中一个表中缺少一行的情况.LEFT JOIN正确地返回这些行的空值,但是,WHERE子句错误地(或意外地)过滤掉这些行.

为什么 - 在这种情况下 - 'null'与任何非空值(如'a')不同?

让我疯狂的是这个

select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t;
Run Code Online (Sandbox Code Playgroud)

返回1行(正如我所料)但是这一点

select t.f1, t.f2
from (select null f1, 'a' f2 from dual) t
where t.f1=t.f2;
Run Code Online (Sandbox Code Playgroud)

返回0行!! 所以null不等于'a',null与'a'不同!!

请...有人可以解释一下吗?

Ama*_*dan 5

究竟.NULL表示一个未知值,而不是任何特定值(它与NULLC中或nilRuby中不同,等等).在SQL中,如果将某些内容与未知值进行比较,结果也是未知的.而且你不会得到WHERE条件未知的行.

试试这个:

SELECT NULL <> 2;
Run Code Online (Sandbox Code Playgroud)

你会看到NULL结果.

试试这个:

SELECT * FROM t WHERE NULL;
Run Code Online (Sandbox Code Playgroud)

即使桌子t很大,也不会出现任何行.

如果你真的需要你所说的你想要的东西(我不是在鼓吹这个),你可以这样做:

SELECT T.f1, T.f2
FROM (SELECT NULL f1, 'a' f2) T
WHERE ((T.f1 IS NULL OR T.f2 IS NULL)
    AND (T.f1 IS NOT NULL OR T.f2 IS NOT NULL))
    OR T.f1 <> T.f2
Run Code Online (Sandbox Code Playgroud)