Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL average multiple columns for each row with nulls

Tags:

sql

sql-server

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.

like image 474
DBA108642 Avatar asked Jun 25 '18 18:06

DBA108642


People also ask

How to find the average of two columns with NULL values?

As some of column contains null value so we cannot use above method for finding the average i.e. col1+col2.... Also we cannot replace NULL with 0 using ISNULL () as it reduces the average value, in short we need to take only those columns in count which has value and need to hide null values i.e. in first row avg should be of (col1+col2+col3)/3.

How to calculate the average of three columns for each row?

The AVG () function in SQL works particular column data. But here, we want to calculate the average of three such columns for each row. In math, we would do AVG= (col1 + col2 + col3)/3

How to count null values in a column in SQL?

How to Count SQL NULL values in a column? The COUNT () function is used to obtain the total number of the rows in the result set. When we use this function with the star sign it count all rows from the table regardless of NULL values. Such as, when we count the Person table through the following query, it will return 19972.

How do you use Avg in SQL with NULL values?

AVG () function and SQL NULL values The AVG () is used to calculate the average value of a result set, that is, it sums all the values ​​in that result set and divides that sum by the number of rows. One point to note about the AVG () function calculation is that NULL values will not be included in the average calculation. 1


Video Answer


3 Answers

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)
like image 195
Paul Abbott Avatar answered Oct 21 '22 13:10

Paul Abbott


I would use apply instead :

select *, (select sum(v) / count(v) 
           from ( values (quality), (Schedule), (CostControl) 
                ) tt(v) 
          ) as AVG
from table t;
like image 20
Yogesh Sharma Avatar answered Oct 21 '22 13:10

Yogesh Sharma


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.

like image 20
Gordon Linoff Avatar answered Oct 21 '22 13:10

Gordon Linoff