空结果集的聚合

时间:2011-06-29 16:52:13

标签: sql postgresql aggregate-functions

我希望空结果集的聚合为0.我尝试了以下内容:

SELECT SUM(COALESCE(capacity, 0))
  FROM objects
 WHERE null IS NOT NULL;

结果:

sum 
-----

(1 row)

子问题:使用SUM(NVL(capacity, 0))

,Oracle上述工作不会

4 个答案:

答案 0 :(得分:10)

the documentation page关于汇总函数:

  

应该注意的是,除了count之外,这些函数在没有选择行时返回空值。特别是,没有行的sum返回null,而不是人们可能期望的零。在必要时,coalesce函数可用于将零替换为null。

因此,如果您想保证返回的值,请将COALESCE应用于SUM结果,而不是其参数:

SELECT COALESCE(SUM(capacity), 0) …

至于Oracle'子问题',我在官方文档页面(the one for 10.2,特别是)找不到任何NULL的概念,但其他两个来源是明确的:

也就是说,您无需将NVL应用于capacity。 (但是,与PostgreSQL中的COALESCE一样,您可能希望将其应用于SUM。)

答案 1 :(得分:5)

问题是,即使没有聚合行(如查询中的情况),聚合也总是返回一行。你总结了一个没有行的表达式。因此,您获得的空值。

请改为尝试:

select coalesce(sum(capacity),0)
from objects
where false;

答案 2 :(得分:1)

这样做:

SELECT COALESCE( SUM(capacity), 0)
FROM objects
WHERE null IS NOT NULL;

顺便说一下,SUM内部的COALESCE是多余的,即使容量为NULL,也不会使摘要为空。

即便:

create table objects
(
    capacity int null
);

insert into objects(capacity) values (1),(2),(NULL),(3);

select sum(capacity) from objects;

这将返回值6,而不是null。

聚合函数内部的合并也是一个性能杀手,因为你的RDBMS引擎不能只是遍历所有行,如果它的值为null,它必须评估每一行的列。我已经看到了一些OCD查询,其中所有聚合查询内部都有一个合并,我认为原始开发具有Cargo Cult Programming的症状,查询方式非常懒散。我删除了SUM内部的合并,然后查询变得很快。

答案 3 :(得分:0)

虽然这篇文章很老,但我想更新我在这种情况下使用的内容

SELECT NVL(SUM(NVL(capacity, 0)),0)
FROM objects
WHERE false;

这里外部NVL避免了结果集中没有行的情况。内部NVL用于空列值,考虑(1 + null)的情况,它将导致null。因此,在列的备用默认值0中,内部NVL也是必要的。