我正在练习SQL,并意识到SQL中的NULL是非常惊人的">实体"。
表">xo"请参阅链接了解表格结构和内容
当我运行以下SQL查询时
select a from xo where a not in (select c from xo) ;
它返回无行。当我运行此查询时
select a from xo where a in (select c from xo);
它按照我预测的方式工作。
你能解释一下上面的事情是如何运作的吗?如果您能提供一些额外的资源来真正理解NULL,那将非常有帮助。
Fiddle
这是因为NULL
在SQL中被特殊处理。每当您将某个东西与NULL
进行比较时,它都会返回未知,这反过来又会使NOT IN
条件下的比较失败。
这就是为什么建议使用EXISTS()
而不是NOT IN
的原因之一。
Fiddle
不要将NOT IN
与子查询一起使用!当子查询返回NULL
值时,它具有您看到的行为。没有返回任何行。
出于这个原因,我强烈推荐NOT EXISTS
或LEFT JOIN
/WHERE
。因此:
select a
from xo
where not exists (select 1 from xo xo2 where xo2.c = xo.a);
这将返回的补码为:
select a
from xo
where exists (select 1 from xo xo2 where xo2.c = xo.a);
发生这种情况的技术原因是NULL
是一个未知值,而不是一个特殊值。因此:
1 in (1, 2, 3) returns TRUE
1 not in (1, 2, 3) returns FALSE
但是:
1 in (1, 2, 3, NULL) returns TRUE, because 1 is explicitly in the list
1 in (2, 3, NULL) returns NULL (equivalent to FALSE) because `NULL` could be 1 or not
和:
1 not in (1, 2, 3, NULL) returns FALSE because 1 is explicitly in the list
1 not in (2, 3, NULL) returns NULL, because 1 could be in the list
因此,当任何值为NULL
时,NOT IN
返回FALSE或NULL
,因此所有行都被过滤掉。