Search code examples
sqlselectnullsql-server-2014ssms-2014

How to deal with null values while DIVIDING


I have a simple looking problem but I don't know how to handle. I have tow columns which are filled by value or null.

I have to make an average of these like this:

  1. if in both are values = (A+B)/2
  2. if one is null then = A or B.

Is it possible to write it in different way then:

 case when a is not null and b is not null then....
 etc.

If I use a simple (a+b)/2 I get null in cases where one of values is null.


Solution

  • Probably the simplest way is to use outer apply with avg() because avg() ignores NULL values:

    select v.avg_ab
    from t outer apply
         (select avg(x) as avg_ab
          from (values (t.A), (t.B)
               ) v
         ) v;
    

    You can also do this with a complicated case expression:

    select (case when A is not NULL and B is not NULL then (A + B) / 2
                 when A is not NULL then A
                 when B is not NULL then B
            end) as avg_ab
    . . .
    

    This works well enough for 2 values; it is feasible for 3. It doesn't generalize well beyond that. Another way to use case is a bit more generalizable:

    select ( (coalesce(A, 0) + coalesce(B, 0)) /
             ((case when A is not null then 1 else 0 end) +
              (case when B is not null then 1 else 0 end)
             )
           )
    

    But the apply method is still simpler.