ANSI SQL standard defines(第6.5章,设置函数规范)对空结果集的聚合函数的以下行为:
COUNT(...) = 0 AVG(...) = NULL MIN(...) = NULL MAX(...) = NULL SUM(...) = NULL
AVG,MIN和MAX返回NULL非常有意义,因为空集的平均值,最小值和最大值是未定义的.
然而,最后一个困扰我:数学上,空集的SUM是明确定义的:0.使用0,加法的neutral element,作为基本情况使一切都一致:
SUM({}) = 0 = 0 SUM({5}) = 5 = 0 + 5 SUM({5,3}) = 8 = 0 + 5 + 3 SUM({5,NULL}) = NULL = 0 + 5 + NULL
将SUM({})定义为null基本上使“无行”成为不适合其他行的特殊情况:
SUM({}) = NULL = NULL SUM({5}) = 5 != NULL + 5 (= NULL) SUM({5,3}) = 8 != NULL + 5 + 3 (= NULL)
我错过了选择(SUM为NULL)的明显优势吗?
解决方法
我担心的原因很简单,规则是以一种特殊的方式设置的(就像ISO sql标准的许多其他“特性”),当时sql聚合及其与数学的联系比现在更难理解(*).
这只是sql语言中极其多的不一致之一.它们使语言更难教,更难学,更难理解,更难使用,更难以达到你想要的任何东西,但这就是事物的方式.由于明显的向后兼容性原因,规则不能改变“冷”和“就像那样”(如果ISO委员会发布标准的最终版本,然后供应商开始实施该标准,那么这些供应商将不会欣赏如果在后续版本中,规则被更改,以至于标准的旧版本的现有(兼容)实现“自动不符合”新版本……)
(*)现在可以更好地理解,如果空集的聚合系统地返回手头的底层二元运算符的标识值(=你所谓的’中性元素’),则它们的行为会更加一致. COUNT和SUM的底层二元运算符是加法,其标识值为零.对于MIN和MAX,如果有关类型是有限的,则该标识值分别是当前类型的最高值和最低值.然而,在这方面,像平均,调和手段,中位数等的情况非常错综复杂,充满异国情调.