Question

Every question I search for about the warning

Warning: Null value is eliminated by an aggregate or other SET operation.

Typically people want to treat the NULL values as 0. I want the opposite, how do I modify the following stored procedure to make it return NULL instead of 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

I thought it would be SET ANSI_NULLS ON (I tried before the declaration, within the procedure itself, and before executing the procedure in my test query) but that did not appear to change the behavior of SUM(.

Was it helpful?

Solution

The sum() function automatically ignores NULL. To do what you want, you need an explicit checK:

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

If you want to be explicit, you could add else NULL to the case statement.

The logic behind this is that count(foo) counts the number of non-NULL values in foo. If this is equal to all the rows, then all the values are non-NULL. You could use the more verbose:

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

And, I want to point out that the title is quite misleading. 1 + NULL = NULL. The issue is with the aggregation functions, not the arithmetic operators.

OTHER TIPS

Looking for a null value with EXISTS may be the fastest:

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

Just say

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
 ...

That's about all you need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top