I have a table like this:
|Quality|Schedule|Cost Control|
-------------------------------
|7 | 8.5 |10 |
|NULL | 9 |NULL |
and I need to calculate the average of each row in the same table so it looks like this:
|Quality|Schedule|Cost Control|AVG|
----------------------------------
|7 | 8.5 |10 |8.5|
|NULL | 9 |NULL |9 |
which I have done using the following code:
SELECT r.Quality, r.Schedule, r.CostControl,
((coalesce(r.quality,0)+
coalesce(r.schedule,0)+
coalesce(r.CostControl,0)/3) as Average
FROM dbo.Rating r
Which gives the following table:
|Quality|Schedule|Cost Control|AVG|
----------------------------------
|7 | 8.5 |10 |8.5|
|NULL | 9 |NULL |3 |
I know the problem is that the divisor is hard coded in my select statement, but I can't figure out how to make it variable. I tried using a case statement to select an addition column:
select Count(case when(r.quality) > 0 then 1 else 0 end +
case when (r.Schedule) > 0 then 1 else 0 end +
case when (r.CostControl) > 0 then 1 else 0 end)
But that only gives me one value. I'm out of ideas and facing a pretty tight deadline, so any help would be much appreciated.
Instead of dividing by 3, use
(CASE WHEN Quality IS NULL THEN 0 ELSE 1 END +
CASE WHEN Schedule IS NULL THEN 0 ELSE 1 END +
CASE WHEN [Cost Control] IS NULL THEN 0 ELSE 1 END)
I would use apply
instead :
select *, (select sum(v) / count(v)
from ( values (quality), (Schedule), (CostControl)
) tt(v)
) as AVG
from table t;
I would use apply
with avg()
:
SELECT r.Quality, r.Schedule, r.CostControl, v.average
FROM dbo.Rating r CROSS APPLY
(SELECT avg(val)
FROM (VALUES (quality), (schedule), (CostControl)) v(val)
) v(average);
This requires no subqueries, no long case
expressions, generalizes easily to more columns, runs no risk of divide-by-zero . . . and the performance might even be equivalent to the case
expression.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.