Null
為什麼 ANSI SQL 將 SUM(無行)定義為 NULL?
ANSI SQL 標準為空結果集上的聚合函式定義(第 6.5 章,集合函式規範)以下行為:
COUNT(...) = 0 AVG(...) = NULL MIN(...) = NULL MAX(...) = NULL SUM(...) = NULL
為 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
定義
SUM({})
為null
基本上使“無行”成為不適合其他情況的特殊情況:SUM({}) = NULL = NULL SUM({5}) = 5 != NULL + 5 (= NULL) SUM({5, 3}) = 8 != NULL + 5 + 3 (= NULL)
我錯過的選擇是否有一些明顯的優勢(SUM 為 NULL)?
恐怕原因很簡單,在 SQL 聚合及其與數學的聯繫不如現在理解的時候,這些規則是以一種特別的方式設置的(就像ISO SQL 標準的許多其他“特性”一樣) (*)。
這只是 SQL 語言中極多的不一致之處之一。它們使語言更難教、更難學習、更難理解、更難使用、更難實現你想要的任何東西,但事情就是這樣。出於向後兼容性的明顯原因,規則不能“冷”和“就那樣”更改(如果 ISO 委員會發布標準的最終版本,然後供應商開始實施該標準,那麼這些供應商將不會欣賞如果在後續版本中,規則被更改,使得標準的前一個版本的現有(兼容)實現“自動不符合”新版本……)
(*) 現在可以更好地理解,如果它們系統地返回手頭底層二元運算符的標識值(= 你稱之為“中性元素”),則空集上的聚合行為會更加一致。COUNT 和 SUM 的底層二元運算符是加法,其標識值為零。對於 MIN 和 MAX,如果相關類型是有限的,則該標識值分別是目前類型的最高和最低值。不過,在這方面,平均、調和平均值、中位數等情況非常複雜和奇特。