我希望空结果集的聚合为0.我尝试了以下内容:
SELECT SUM(COALESCE(capacity, 0))
FROM objects
WHERE null IS NOT NULL;
结果:
sum
-----
(1 row)
子问题:使用SUM(NVL(capacity, 0))
?
答案 0 :(得分:10)
从the documentation page关于汇总函数:
应该注意的是,除了
count
之外,这些函数在没有选择行时返回空值。特别是,没有行的sum
返回null,而不是人们可能期望的零。在必要时,coalesce
函数可用于将零替换为null。
因此,如果您想保证返回的值,请将COALESCE
应用于SUM
的结果,而不是其参数:
SELECT COALESCE(SUM(capacity), 0) …
至于Oracle'子问题',我在官方文档页面(the one for 10.2,特别是)找不到任何NULL的概念,但其他两个来源是明确的:
SUM([DISTINCT] n)
n的值总和,忽略NULL
sum aggregate function [Oracle SQL]:
...如果在某些数字上创建了sum(),则忽略 nulls ,如下例所示......
也就是说,您无需将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也是必要的。