为什么在Oracle中SUM(null)不为0?

Moh*_*ari 12 sql database oracle plsql

当遇到空值时,可以理解解释Oracle中SUM函数的内部功能:
结果

select sum(null) from dual;
is null
Run Code Online (Sandbox Code Playgroud)

但是当一个空值出现在值序列中时(如无效列的总和),空值的计算值将为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
Run Code Online (Sandbox Code Playgroud)

当看到结果时,这会更有趣

select (1 + null) from dual
is null
Run Code Online (Sandbox Code Playgroud)

因为任何null操作都将导致null(is null运算符除外).

==========================
由于评论的一些更新:

create table odd_table as select sum(null) as some_name from dual;
Run Code Online (Sandbox Code Playgroud)

将导致:

create table ODD_TABLE
(
  some_name NUMBER
)
Run Code Online (Sandbox Code Playgroud)

为什么some_name列的类型

das*_*ght 10

SQL NULL在计算时不会将值视为零SUM,它会忽略它们:

返回DISTINCT表达式中所有值或仅值的总和.空值被忽略.

这仅在一种情况下产生差异 - 当总计的序列不包含数字项时,仅NULLs:如果存在至少一个数字,则结果将是数字.


Dav*_*dge 10

如果您正在寻找此行为的基本原理,那么可以在ANSI SQL标准中找到它,该标准规定聚合运算符忽略NULL值.

如果您想覆盖该行为,那么您可以自由地:

Sum(Coalesce(<expression>,0))
Run Code Online (Sandbox Code Playgroud)

......虽然用Sum()来表达更有意义......

Coalesce(Sum(<expression>),0)
Run Code Online (Sandbox Code Playgroud)

你可能更有意义:

Avg(Coalesce(<expression>,0))
Run Code Online (Sandbox Code Playgroud)

... 要么 ...

Min(Coalesce(<expression,0))
Run Code Online (Sandbox Code Playgroud)

其他ANSI聚合怪癖:

  1. Count()永远不会返回null(当然还是否定的)
  2. 仅选择没有Group By的聚合函数将始终返回单行,即使没有可供选择的数据.

所以......

Coalesce(Count(<expression>),0)
Run Code Online (Sandbox Code Playgroud)

......浪费了良好的凝聚力.