2016-12-19 9 views
1

У меня есть простая проблема, но я не знаю, как обращаться. У меня есть буксирные колонны, которые заполняются значением или null.Как работать с нулевыми значениями в то время как DIVIDING

я должен сделать в среднем это так:

  1. если оба значения = (А + В)/2
  2. , если равно нулю, то = А или В.

можно ли писать по-другому, то:

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

Если я использую простой (a+b)/2 я получаю null в случаях, когда одно из значений: null.

+0

'сливаются ((а + б)/2, Ь, а)'? – TZHX

+0

Какое должно быть значение, если оба A, B являются NULL? – Stavr00

+0

um ... возможно, я что-то пропустил, но AVG() http://stackoverflow.com/questions/7367750/average-of-multiple-columns и проверить ответ Мартина. – xQbert

ответ

3

Вероятно, самым простым способом является использование outer apply с avg(), поскольку avg() игнорирует NULL значения:

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

Вы также можете сделать это с помощью сложной case выражения:

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

Это работает достаточно хорошо 2 значения; это возможно для 3. Оно не обобщает далеко за пределы этого. Другой способ использования case немного более обобщенным:

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

Но метод apply еще проще.

+0

Это ужасное решение для запроса OP. –

3

Предполагая случай, когда оба они null должен привести в среднем null, вы можете использовать математический «трюк» из (A+A)/2=A и использовать coalesce, чтобы написать это в довольно элегантной моде, ИМХО:

(COALESCE(a, b) + COALESCE(b, a))/2 
+1

Я всегда забываю о COALESCE! –

+0

Ну а если у меня их четверо? Тогда мне пришлось бы использовать: (a, b, c, d) и все преобразования?И если один из них не равен нулю, я бы разделил на 2 только одно значение, не так ли? – HeadOverFeet

0

Попробуйте следующее:

SELECT (ISNULL(a, b)+ISNULL(b, a))/2 
1

Это будет чистое решение

select coalesce((A+B)/2,A,B) 

.
.
.

Демонстрация:

declare @t table (id int,A int,B int) 

insert into @t values (1,30,50),(2,30,null),(3,null,50),(4,null,null) 

select id,A,B,coalesce((A+B)/2,A,B) as result 
from @t 

+----+------+------+--------+ 
| id | A | B | result | 
+----+------+------+--------+ 
| 1 | 30 | 50 | 40  | 
+----+------+------+--------+ 
| 2 | 30 | NULL | 30  | 
+----+------+------+--------+ 
| 3 | NULL | 50 | 50  | 
+----+------+------+--------+ 
| 4 | NULL | NULL | NULL | 
+----+------+------+--------+