本节书摘来自异步社区出版社《Oracle SQL疑难解析》一书中的第1章,第1.13节,作者: 【美】Grant Allen , Bob Bryla , Darl Kuhn,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.13 在语句中找到和消除空值
Oracle SQL疑难解析
1.13.1 要解决的问题
我们需要统计出公司中,有多少员工的薪酬里含销售提成(commission percentage),有多少员工的薪酬是固定工资。我们可以用HR.EMPLOYEES表中的COMMISSION_PCT字段来获得数据。
1.13.2 解决方法
HR.EMPLOYEES表的结构允许COMMISSION_PCT字段为空值。有两个查询语句可以分别查找commission percent为空值的人和为非空值的人。首先,查找commission percentage为空值的员工:
select first_name, last_name
from hr.employees
where commission_pct is null;
FIRST_NAME LAST_NAME
-------------------- -------------------------
Donald OConnell
Douglas Grant
Jennifer Whalen
Michael Hartstein
Pat Fay
…
72 rows selected.
现在查找commission percentage为非空值的人员:
select first_name, last_name
from hr.employees
where commission_pct is not null;
FIRST_NAME LAST_NAME
-------------------- -------------------------
John Russell
Karen Partners
Alberto Errazuriz
Gerald Cambrault
Eleni Zlotkey
…
35 rows selected.
1.13.3 数据库如何工作
第一个SELECT语句用“COMMISSION_PCT IS NULL”子句测试NULL项。这只会出现两个结果:要么字段为空,即没有值,满足查询条件;要么字段有值。
第二个语句用“COMMISSION_PCT IS NOT NULL”子句,这将找出COMMISSION_PCT 实际值对应的所有EMPLOYEE。
Oracle对空字符串的非标准处理
SQL标准做法是用空或零长度的字符串来代表NULL值,而Oracle并非如此。其中历史的、地域的原因我们无需深究,但一定要记住,Oracle对NULL的规定和用法。对于几乎所有的其他数据库,SQL都把空字符串当作一个独立的、已知的值。
有编程背景的人会发现一些类似的规定,一个0长度的字符串只有一个字符串终结符(0)作为其内容。相反,一个加密的字符串没有确定的状态……即使是一个终结符。我们不能把0长度和未知状态的字符串进行互换,这类似于Oracle如何对待NULL。
1.13.4 NULL不跟任何值相等
在SQL中涉及NULL值的使用诀窍,也是每天必须面对的功课,这经常让人不知所措。每个SQL表达式的结果都是三个值选一:“真”、“假”或“空”。在各种比较、逻辑操作和判断中都是如此。但为避免偶尔的遗忘,我们还是要一再地强调:NULL不跟任何值相等,任何值不跟NULL相等,NULL不等于NULL。试着运行下面的语句,看看你能预猜到答案吗?
select first_name, last_name
from hr.employees
where commission_pct = NULL;
结果是没有任何行返回。即使从前面的SELECT查询中看到EMPLOYEE_ID是72的员工的COMMISSION_PCT为NULL,但因为NULL不等于NULL,所以COMMISSION_PCT=NULL是不成立的,所以查询的结果是没有记录返回。记住,不要用“=”号,而是永远用“IS NULL”或“IS NOT NULL”来寻找或排除NULL值。