我有医生姓名和州的表格。
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会导致某些问题。有人能为我解释一下吗?是否有替代我想做的事情?
由于
答案 0 :(得分:3)
是的,还有另一种选择 - 如果你想坚持使用ANSI标准,你可以使用NVL()
功能(或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
例如将返回零行。您与NULL
和IS NULL
进行IS NOT NULL
次比较。
答案 1 :(得分:3)
如前所述,你不知道Michael Crane的州不是马里兰州。它是NULL,可以理解为代表不知道&#34;。它可能是马里兰州,也可能不是。 NOT IN ('MD')
只会发现那些已知的值不是'MD'
。
如果您有过滤器WHERE x
,则可以使用MINUS
准确查找x
不为真的记录(其中x
为假或未知)。
select *
from doctors
minus
select *
from doctors
where state in ('MD');
这比涉及IS NULL
或NVL
的任何内容都有一个很大的优势:它可以直接显示您 想要查看哪些记录。您不必担心意外遗漏一个NULL
未涵盖您的情况的案例,并且您不必担心碰巧与您的虚拟值相匹配的记录与NVL
一起使用。
它通常不利于Oracle上的性能,访问表两次,但对于一次性查询,根据表大小,写入查询所节省的时间可能超过添加的执行时间。 / p>
答案 2 :(得分:0)
在数据库内部,null不是物理字符串值(&#34; null&#34;),它只是没有值。因此,如果将NULL与任何东西进行比较,它将不相等或不相等。甚至,两个NULL不相等。您只能检查值是否为NULL,但您无法将其与其他值进行比较。