为什么 ANSI SQL 将 SUM(无行)定义为 NULL?

Hei*_*nzi 30 null aggregate relational-theory sql-standard

ANSI SQL标准定义(第6.5章,集功能规范),用于空的结果集的集合函数以下行为:

COUNT(...) = 0
AVG(...) = NULL
MIN(...) = NULL
MAX(...) = NULL
SUM(...) = NULL
Run Code Online (Sandbox Code Playgroud)

为 AVG、MIN 和 MAX 返回 NULL 非常有意义,因为空集的平均值、最小值和最大值是未定义的。

然而,最后一个让我感到困扰:在数学上,空集的 SUM 是明确定义的:0。使用 0,加法的中性元素,作为基本情况使一切保持一致:

SUM({})        = 0    = 0
SUM({5})       = 5    = 0 + 5
SUM({5, 3})    = 8    = 0 + 5 + 3
SUM({5, NULL}) = NULL = 0 + 5 + NULL
Run Code Online (Sandbox Code Playgroud)

定义SUM({})null基本上使“无行”成为不适合其他行的特殊情况:

SUM({})     = NULL  = NULL
SUM({5})    = 5    != NULL + 5 (= NULL)
SUM({5, 3}) = 8    != NULL + 5 + 3 (= NULL)
Run Code Online (Sandbox Code Playgroud)

我错过的选择(SUM 为空)是否有一些明显的优势?

Erw*_*out 20

恐怕原因很简单,因为在 SQL 聚合及其与数学的联系不如现在了解的情况下,这些规则是以一种特殊的方式设置的(就像ISO SQL 标准的许多其他“功能”一样) (*)。

这只是 SQL 语言中极其众多的不一致之处之一。它们使语言更难教、更难学、更难理解、更难使用、更难达到任何你想要的,但事情就是这样。出于向后兼容性的明显原因,不能“冷”和“就那样”更改规则(如果 ISO 委员会发布标准的最终版本,然后供应商开始实施该标准,那么这些供应商将不会欣赏如果在后续版本中,规则发生了变化,那么旧版本标准的现有(兼容)实现“自动不符合”新版本......)

(*) 现在可以更好地理解,如果空集合上的聚合系统地返回手头底层二元运算符的标识值(= 您所说的“中性元素”),它们的行为会更加一致。COUNT 和 SUM 的底层二元运算符是加法,其标识值为零。对于 MIN 和 MAX,如果相关类型是有限的,则该标识值分别是当前类型的最高值和最低值。不过,平均数、调和平均数、中位数等情况在这方面非常复杂和奇特。

  • MIN 和 MAX 差别不大。分别采用底层二元运算符 LOWESTOF(x,y) 和 HIGHESTOF(x,y)。这些二元运算符确实具有标识值。因为在这两种情况下(如果涉及的类型是有限的),确实存在一些值 z 使得 forall x : LOWESTOF(z,x)=x 和 forall y : HIGHESTOF (y,z)=y。(两种情况的恒等值并不相同,但两种情况确实存在。)我同意结果乍一看非常违反直觉,但不可否认数学现实。 (5认同)