Стандарт ANSI SQL определяет (глава 6.5, спецификация функции набора) следующее поведение для агрегатных функций в пустых результирующих наборах:
COUNT(...) = 0
AVG(...) = NULL
MIN(...) = NULL
MAX(...) = NULL
SUM(...) = NULL
Возврат NULL для AVG, MIN и MAX имеет смысл, поскольку среднее, минимальное и максимальное значения пустого набора не определены.
Последний, однако, беспокоит меня: Математически 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({})
as в null
основном делает «без строк» особым случаем, который не вписывается в другие:
SUM({}) = NULL = NULL
SUM({5}) = 5 != NULL + 5 (= NULL)
SUM({5, 3}) = 8 != NULL + 5 + 3 (= NULL)
Есть ли какое-то очевидное преимущество сделанного выбора (SUM, NULL), который я пропустил?
Ответы:
Я боюсь, что причина в том, что правила были установлены по принципу ad hoc (как и многие другие «особенности» стандарта ISO SQL) в то время, когда агрегаты SQL и их связь с математикой были менее понятны, чем сейчас (*).
Это всего лишь одна из чрезвычайно многих несоответствий в языке SQL. Они делают язык труднее учить, труднее учить, труднее понять, труднее использовать, труднее всего, что вы хотите, но это просто так. Правила не могут быть изменены «холодными» и «просто так» по очевидным причинам обратной совместимости (если комитет ИСО публикует окончательную версию стандарта, а поставщики затем собираются внедрить этот стандарт, то эти поставщики не оценят это очень сильно, если в последующей версии правила изменяются так, что существующие (совместимые) реализации прежней версии стандарта «автоматически не соответствуют» новой версии ...)
(*) Теперь лучше понять, что агрегаты по пустому набору ведут себя более согласованно, если они систематически возвращают значение идентичности (= то, что вы называете «нейтральным элементом») базового бинарного оператора под рукой. Этот базовый двоичный оператор для COUNT и SUM является сложением, а его значение идентичности равно нулю. Для MIN и MAX это значение идентификатора является наивысшим и наименьшим значением имеющегося типа, соответственно, если рассматриваемые типы конечны. Однако случаи, такие как усреднение, гармонические средние, медианы и т. Д., Чрезвычайно сложны и экзотичны в этом отношении.
источник
HIGHEST()
многих, не является элементом типа данных, например, для Реалов, где идентичность будет-Infinity
(и+Infinity
дляLOWEST()
)В прагматическом смысле существующий результат
NULL
полезен. Рассмотрим следующую таблицу и утверждения:Первый оператор возвращает NULL, а второй возвращает ноль. Если бы пустой набор возвратил ноль,
SUM
нам понадобится другое средство, чтобы отличить истинную сумму нуля от пустого набора, возможно, используя count. Если мы действительно хотим ноль для пустого множества, то простоеCOALESCE
будет соответствовать этому требованию.источник
COALESCE()
подобным образом не будет отличать0
сумму ( ) пустого набора отNULL
суммы () (скажем, в таблице есть(10, NULL)
строка.SUM
столбец и получаю ноль, я знаю, не проверяя, есть ли хотя бы одна строка, не равная NULL, для отображения результата.DECODE(count(c2),0,NULL,sum(c2))
когда оно есть.Основное различие, которое я вижу, это тип данных. COUNT имеет четко определенный тип повторения: целое число. Все остальные зависят от типа столбца / выражения, на которое они смотрят. Их тип возвращаемого значения должен быть совместим со всеми членами набора (например, с плавающей точкой, валютой, десятичной дробью, bcd, timespan, ...). Поскольку нет набора, вы не можете подразумевать тип возвращаемого значения, поэтому NULL - ваш лучший вариант.
Примечание. В большинстве случаев вы можете подразумевать тип возвращаемого значения для типа столбца, который вы просматриваете, но вы можете делать SUMs не только для столбцов, но и для всех видов вещей. Подразумевать, что тип возврата может быть очень трудным, если не невозможным, при определенных обстоятельствах, особенно когда вы думаете о возможных расширениях стандарта (на ум приходят динамические типы).
источник
SUM(column)
выражении? Разве у нас нет пустых таблиц - и там все столбцы имеют определенные типы? Почему это должно быть иначе для пустого набора результатов?24 + 56.07 + '2012-10-05' + 'Red'
? Я имею в виду, что нет смысла беспокоиться о том, какSUM()
себя поведет, когда у нас возникнут проблемы с определением дополнения.