Reputation: 11712
I have a table with integer values. They could be negative, 0, positive and NULL. I need treat NULL as 0, calculate average for a given date and if average value is less than 0 then put 0 there.
My query is the following:
select
Id,
ValueDate,
case
when avg(isnull(Value, 0)) > 0 then avg(isnull(Value, 0))
else 0
end AvgValue
from SomeTable
where ValueDate = @givenDate
group by Id, ValueDate
How to avoid double aggregate function definition in case statement (aggregate statement could be much more complex)?
Upvotes: 1
Views: 1049
Reputation: 43646
This is a solution without creating implementation of any not build-in functions. I know your example will be more complex but this is just an idea:
CREATE TABLE DataSource
(
[ID] TINYINT
,[Value] INT
)
INSERT INTO DataSource ([ID], [Value])
VALUES (1, 2)
,(1, 0)
,(1, NULL)
,(1, 98)
,(1, NULL)
,(2, -4)
,(2, 0)
,(2, 0)
,(2, NULL)
SELECT [ID]
,MAX([Value])
FROM
(
SELECT [ID]
,AVG(COALESCE([Value],0))
FROM DataSource
GROUP BY [ID]
UNION ALL
SELECT DISTINCT [ID]
,0
FROM DataSource
) Data([ID],[Value])
GROUP BY [ID]
Here is the fiddle - http://sqlfiddle.com/#!6/3d223/14
Upvotes: 1
Reputation: 13725
I think the greatest function could help you:
select
Id,
ValueDate,
greatest(avg(isnull(Value, 0)),0) AvgValue
from SomeTable
where ValueDate = @givenDate
group by Id, ValueDate
Upvotes: 2