T-SQL中的Select查询(续4)
这两天因房子问题,实在抽不出空来,这不现在趁午休时间,就把该“T-SQL中的Select查询”系列结个尾吧!
今天呢,让我们一起来探讨一下“空值”的相关问题吧!
在关系数据库模型中使用空值来表示缺失的数据。在实际中,空值说明还没有向数据库中输入相应的数据,或者某个特定的纪录行暂不需要使用该列。从技术的角度来说,空值表示“未知的值”,任何包含空值的表达式的计算结果也是空值。例如:如果一个银行帐户的资金量是未知的,而某个资产组合又包含了这个帐户的资金,那么整个资产组合的总价值也就是未知的。同样如此,在SQL中这个概念也是正确的。用一个较有名的DBA的话来说就是:“空值夺去了所有其他值的生命”!
因为空值具有使整个表达式的计算结果为空的特性,所以一些开发人员不愿意使用这个空值。他们在开发数据库时从不使用空值,而是把列的默认值设置为其他替代空值的值(如空字符串、0、或者‘n/a’)。其他数据库开发人员则认为:不能仅仅为了编写代码的方便而用0或者空字符串来表示未知的值。我就属于这第二个阵营。空值对于数据库是很有价值的,因为它们能够提供关于数据状态的重要信息,所以值得编写代码来对空值进行恰当地检查和处理。
(一)检测空值
要知道,一个空值并不等于另一个空值。即:如果编号为123的帐户中的资金量是未知的,同时编号为234的帐户中资金量也是未知的,那么,从逻辑上是无法证明这两个帐户中的资金量是相等的,因为相等运算符不能检测空值,所以SQL引入了一个特殊的操作符is来检测特殊值之间的等价性,其语法是:
WHERE Expression IS NULL
如:IF NULL IS NULL
SELECT ‘IS’
ELSE
SELECT ‘IS NOT’
执行结果为:IS
又如:下面的查询只检索NickName列上具有空值的那些客户:
SELECT FirstName,LastName,NickName
FROM dbo.Customer
WHERE NickName IS NULL
ORDER BY LastName,FirstName
其执行结果为:
FirstName LastName NickName
-------------------- ------------------------ -------------------
Debbie Andrews NULL
Dave Bettys NULL
Jay Brown NULL
… …
注意:1. 使用=来检测空值,其结果是不成功的!
2. 聚合函数在对包含空值的列中的数据进行累计时所采用的方法与上述的规则(即将空值与一个非空的值相加其结果也是空值)不同,聚合函数(例如Sum()、Avg()等)往往会忽略空值。
(二)处理空值
当为报表、最终用户或者一些应用程序提供数据的时候,空值是不受欢迎的,通常需要将空值转换为一个有效的值,以便于对数据的理解。
Isnull()和coalesce()函数可以将空值转换为有效的值,而nullif()函数可以根据指定的条件来生成空值。
为了处理更为复杂的情况,SQL Server在处理布尔表达式时使用了三态逻辑,将空值与真值进行比较,其结果也是一个空值。
1. 使用IsNull()函数
首先注意它与is null查找条件是不同的。Isnull() 函数具有两个参数,第一个参数是单个列或者表达式,第二个参数则是一个替代值。如果第一个参数的值是一个有效的值(非空的),isnull()函数就会返回第一个参数的值。如果第一个参数的值是空值,isnull()就会返回第二个参数的值来替代空值,如:
SELECT FirstName,LastName,ISNULL(NickName,’none’)
FROM Customer
ORDER BY LastName, FirstName
执行结果为:
FirstName LastName NickName
----------------------- --------------------- ---------------------
Joe Adams Slim
Melissa Anderson Missy
Debbie Andrews none
Dave Bettys none
… …
警告:1.isnull()和nullif()函数都是T-SQL专有的,它们不符合ANSI的SQL标准!!
2. Coalesce()函数
它可以将多个表达式或者列作为参数,并返回第一个非空的值,如:SELECT Coalesce(NULL,1+NULL,1+2,’abc’)
其执行结果为:3
3.Nullif()函数
Nullif()具有两个参数,如果这两个参数相等,它就会返回一个空值;否则,它会返回前一个参数的值。如:下面的例子将把NickName列中的空字符串转换为空值。为了说明的需要,我使用了第一个update语句将一个客户的昵称改为空字符串:
UPDATE Customer
SET NickName=’’
WHERE LastName=’Adams’
SELECT LastName,FirstName,
CASE NickName
WHEN ‘’ THEN ‘blank’
ELSE NickName
END AS NickName,
Nullif(NickName,’’) as NickNameNullIf
FROM dbo.Customer
WHERE LastName IN(‘Adams’, ‘Anderson’,’Andrews’)
ORDER BY LastName,FirstName
执行的结果为:
LastName FirstName NickName NickNameNullIf
------------------ -------------------- ------------------ --------------------------
Adams Joe blank NULL
Anderson Melissa Missy Missy
Andrews Debbie NULL NULL
第三个列使用了case表达式将空字符串显示为“blank”,并且在第四个列中,nullif()确实把空字符串转换为了空值。而在其他几种情况下,Melissa的昵称没有受到nullif()的影响,而Debbie在NickName列上的空值也没有改变。
好了,至此,我与大家就“T-SQL中的Select查询”的交流到此为止!
我很希望各位同仁看后,或留言加以评论,或发E-Mail
,共同进步!谢谢!~