数据库函数AVG 中的0 和NULL
无论在什么数据库里,0和NULL值是有区别的,为了明确说明这个问题,我们来举个例子说明,比如在盘点商品库存的时候,某种商品没有了,那么它的数量是我们应该输入0,代表这种商品已经没有了,而另一种商品,我们尚未来得及清点,因此,它的数量一栏是空的,也就是我们所说的空值,这种空值告诉我们,我们应该去清点这种商品的数量,工作尚未完成,而不是告诉我们这种商品是0,在此,我们可以很清楚地看到,0和NULL是不一样的,它切实地反应了事物的两种完全不一样的状态。当然,这也不是绝对的,有时候0和NULL也确实代表着同一种状态,当然,这完全取决于您的理解,您也可以理解不同的状态,我们在这里重点讨论一下平均值的计算。
说起计算平均值,可能一些初学者会不屑一顾,不就是平均值
吗?AVG(expression),对吧?我只能说,你这不算错,可也不算对。我们来看下面的列表(假定表名为USERAGE):
ID1234 USERAGE梅兰竹菊
AGE4020NULL0
我们先不考虑现实中有没有0岁的,我们权当这是一个例子,我们现在要对这个表来计算平均值,你应该
怎么算?
SELECT AVG(AGE)FROM USERAGE
我可以告诉你,你计算的结果一定是20,或许你认为应该计算的是15,对吧?这倒不是AVG函数的问题,这是这个函数的用法决定的,AVG在计算列的平均值的时候,会自动排除空(NULL),也就是说,你明明看到是4条记录,实际上是当做3条记录在计算,或许你对此很不满,想这么来算:我不管你有NULL 还是0,我就是要计算这4个人的平均数做,也可以,你可以这样写代码:
SELECT AVG(ISNULL(AGE,0))FROM USERAGE
执行吧,怎么样,结果是15了吧?ISNULL函数的用法在在计算中如遇到空值,自动用后面的值替换,在这里我们指定的参数是0,所以就用0替换掉了
空值,所以,这次,SQL Server是按4条记录计算的。至于ISNULL的更多情况,你可以查联机从书。或许有时候,有些场合,你需要将所有的0和空值都
排除掉,只计算那些实在的值的平均数,这也是可以做到的,你可以这样写代码:
SELECT AVG(NULLIF(AVG,0))FROM USERAGE
执行,呵呵,这次计算的结果是30,把空值和0都排除掉了,NULLIF函数的用法就是比较2个表达式,若两个参数表达式值一样,就返回空值,我们这
样写,就是将每一个值与0比较,如果不相等,就返回第一个表达式的值,这里,如果有NULL和实际的数就返回给AVG函数,如果遇到0,呵呵,对不起,
两值想等,就返回空值,这样一来,所有的0都给替换成了空值,而AVG的本
性又会把NULL都彻底排除,而原本的0也不例外(给换成了空值了呀),现在,你应该对求平均值有一个大概的了解了吧。
最后在罗嗦一句,我们有时候想知道某一个表里存储了多少条数据(根据数字标识符的最大数字判断是很愚蠢的做法,因为引起标识符空缺的原因太多了),比如上面那个表,我们可能会这么写:
SELECT COUNT(*)FROM USERAGE
也有可能会这么写:
SELECT COUNT(AGE)FROM USERAGE
以上这2种写法都有可能出现的,前者是因为COUNT(*)写起来简单,尤其
是字段标识符比较长的时候,我们这样写比较省事,而后者,则使计算机的处
理更高效,减轻计算机的负担,一般有推荐第二种写法,前一种写法一定能给
你所要的结果,比如这里,执行之后返回值一定是4,而第二种写法就要小心了,首先我认可这种写法,但是你要注意到一个问题,这里,按第二种写法,
执行之后,返回值一定是3,它也像AVG那样排除掉了空值,你要的是这个表
的记录数量,看看它给了我们什么?使用第二种写法最好是用在主键上,或者具
isnull的用法
有NOT NULL属性的字段列上,这对初学者来说是一个巨大的陷阱(如果你对0和NULL的区别不上心的话),如果你某些场合恰好没有使用SUM函数,使用了AVG(AGE)先求平均值,再使用COUNT(*)来求记录数量,之后再相乘得到总和…天啊,看看你都干了些什么…
MSN空间完美搬家到新浪博客!