如果添加 "NOT IN" 则缺少记录

Missing records if add "NOT IN"

我有一个 table 的医生姓名和州。

f_name  | l_name | state
MICHAEL | CRANE  | 
HAL     | CRANE  | MD
THOMAS  | ROMINA | DE

以此类推

我想要的是让所有不是医学博士的医生。但是,如果我写这个表达式,我会遗漏那些状态为 NULL 值的表达式。

SELECT *
FROM doctors
WHERE state NOT IN ('MD')

我不明白这个问题。我能够通过添加

来修复它
OR state IS NULL

显然它与 NOT IN(或 IN)不处理 NULL 有关。谁能为我解释一下?我尝试做的事情有替代方案吗?

谢谢

是的,还有一个替代方案 - 您可以使用 NVL() 函数(如果您想坚持 ANSI 标准,则可以使用 COALESCE()):

SELECT * FROM doctors
 WHERE NVL(state, '@@') NOT IN ('MD')

然而你并不真的需要在这里使用 NOT IN - 只有当你有多个值时才有必要,例如:

SELECT * FROM doctors
 WHERE NVL(state, '@@') NOT IN ('MD','PA')

对于一个值,您可以只使用 =(或者在这种情况下,!=<>):

SELECT * FROM doctors
 WHERE NVL(state, '@@') != 'MD'

在 Oracle SQL 中,NULL 无法与其他值(甚至其他 NULL 相比)。例如,WHERE NULL = NULL 会将 return 零行。您将 NULLIS NULLIS NOT NULL 进行比较。

如前所述,您不知道 Michael Crane 所在的州不是马里​​兰州。它是 NULL,可以理解为代表 "don't know"。它可能是马里兰州,也可能不是。 NOT IN ('MD') 仅发现那些值 已知 不是 'MD'.

如果您有过滤器 WHERE x,您可以使用 MINUS 准确查找 x 不正确的记录(其中 x 为假或未知).

select *
from doctors
minus
select *
from doctors
where state in ('MD');

与涉及 IS NULLNVL 的任何内容相比,这有一个很大的优势:您 不想 想看哪些记录会立即显而易见。您不必担心意外遗漏 NULL 未包含在您的条件中的情况,并且您不必担心记录恰好与您使用 [=18= 的任何虚拟值相匹配].

在 Oracle 上一般性能不好,访问 table 两次,但是对于一次性查询,根据 table 的大小,编写查询节省的时间可能超过增加的执行时间。

在数据库中,null 不是物理字符串值("null"),它只是表示没有值。所以,如果你将 NULL 与任何东西进行比较,它将不等于或不等于。甚至,两个 NULL 也不相等。您只能检查一个值是否为 NULL,但不能将其与其他值进行比较。