当元素为NULL时,将聚合函数更改为输出NULL

时间:2014-03-03 21:46:56

标签: sql sql-server stored-procedures null sql-server-2012

我搜索有关警告的每个问题

  

警告:聚合或其他SET操作消除了空值。

通常人们希望将NULL值视为0.我想要反过来,如何修改以下存储过程使其返回NULL而不是1?

CREATE PROCEDURE TestProcedure 
AS
BEGIN
select cast(null as int) as foo into #tmp

insert into #tmp values (1)

select sum(foo) from #tmp
END
GO

我认为它是SET ANSI_NULLS ON(我在声明之前尝试过,在程序本身内,在我的测试查询中执行过程之前),但这似乎没有改变SUM(的行为

3 个答案:

答案 0 :(得分:6)

sum()功能会自动忽略NULL。要做你想做的事,你需要一个明确的checK:

select (case when count(foo) = count(*) then sum(foo) end)
from #tmp;

如果您想要明确,可以将else NULL添加到case声明中。

这背后的逻辑是count(foo)计算foo中非NULL值的数量。如果这等于所有行,则所有值都是非NULL。你可以使用更详细的:

select (case when sum(case when foo is null then 1 else 0 end) > 0
             then sum(foo)
        end)

并且,我想指出标题是非常误导的。 1 + NULL = NULL。问题在于聚合函数,而不是算术运算符。

答案 1 :(得分:2)

使用EXISTS寻找空值可能是最快的:

SELECT
    CASE WHEN EXISTS(SELECT NULL FROM tmp WHERE foo IS NULL)
        THEN NULL
        ELSE (SELECT sum(foo) from tmp)
    END

答案 2 :(得分:0)

说完

select case sign(sum(case when foo is null then 1 else 0 end))
       when 1 then null
       else        sum(foo)
       end
 from some_table
 ...
 group by
 ...

这就是你所需要的一切。