Почему SUM (null) не является 0 в Oracle?

Было бы полезно пояснить внутреннюю функциональность функции SUM в Oracle при столкновении с нулевыми значениями:
Результат

select sum(null) from dual;
is null

Но когда нулевое значение находится в последовательности значений (например, сумма столбца с нулевым значением), вычисленное значение нулевого значения будет 0

select sum(value) from
(
select case when mod(level , 2) = 0 then null else level end as value from dual
connect by level <= 10
)
is 25

Это будет более интересно при просмотре результата

select (1 + null) from dual
is null

Так как любая операция с нулевым значением приведет к null (кроме оператора is null).

==========================

Некоторое обновление из-за комментариев:

create table odd_table as select sum(null) as some_name from dual;

Результат:

create table ODD_TABLE
(
  some_name NUMBER
)

Почему столбец some_name имеет тип номер?

Ответ 1

SQL не обрабатывает значения NULL как нули при расчете SUM, он игнорирует их:

Возвращает сумму всех значений или только значений DISTINCT в выражении. Нулевые значения игнорируются.

Это имеет значение только в одном случае - когда суммированная последовательность не содержит числовых элементов, только NULL s: если присутствует хотя бы одно число, результат будет числовым.

Ответ 2

Если вы ищете обоснование этого поведения, его можно найти в стандартах ANSI SQL, которые диктуют, что агенты агрегации игнорируют значения NULL.

Если вы хотите переопределить это поведение, вы можете:

Sum(Coalesce(<expression>,0))

... хотя с Sum() было бы более разумно...

Coalesce(Sum(<expression>),0)

Вы могли бы более значимо:

Avg(Coalesce(<expression>,0))

... или...

Min(Coalesce(<expression,0))

Другие атрибуты агрегации ANSI:

  • Count() никогда не возвращает нуль (или отрицательный, конечно)
  • Выбор только функций агрегации без группы By всегда будет возвращать одну строку, даже если нет данных, из которых можно выбрать.

Итак...

Coalesce(Count(<expression>),0)

... является пустой тратой хорошего коалесценции.

Ответ 3

Вы смотрите на это неправильно. SUM() работает с столбцом и игнорирует нули.

Процитировать документацию:

Эта функция принимает в качестве аргумента какой-либо числовой тип данных или любой нечетный тип данных, который может быть неявно преобразован в числовой тип данных. Функция возвращает тот же тип данных, что и числовой тип данных аргумента.

NULL не имеет типа данных, поэтому ваш первый пример должен возвращать значение null; поскольку NULL не является числовым.

Второй пример суммирует числовые значения в столбце. Сумма 0 + null + 1 + 2 равна 3; NULL просто означает, что числа здесь не существует.

Третий пример - это не операция в столбце; удалите SUM(), и ответ будет таким же, как ничто + 1 все еще не имеет значения. Вы не можете наложить NULL на пустой номер, как вы можете, с помощью строки, поскольку нет такой вещи, как пустое число. Это либо существует, либо нет.

Ответ 4

Арифметические агрегированные функции игнорируют нули.

  • SUM() игнорирует их
  • AVG() вычисляет среднее значение, как если бы нулевые строки не существовали (нули не учитываются в сумме или делителе)

Ответ 5

Как отметил Богемиан, как SUM, так и AVG исключают записи с NULL в них. Эти записи не входят в совокупность. Если AVG обрабатывает NULL-записи как ноль, это приведет к смещению результата к нулю.

Может показаться случайному наблюдателю, как будто SUM обрабатывает NULL записи как ноль. Это действительно исключает их. Если все записи исключены, результат не имеет значения, что равно NULL. Ваш пример иллюстрирует это.

Ответ 6

Это неверно: сумма 0 + null + 1 + 2 равна 3; выберите 0 + null + 1 + 2 всего от двойного;

Результат равен нулю! Аналогичные утверждения дают результат null, если любой операнд имеет значение null.