1

我有一个看起来很简单的问题,但我不知道如何处理。我有两列由值或填充null

我必须像这样对这些进行平均:

  1. 如果两者都是值 = (A+B)/2
  2. 如果一个为空,则 = A 或 B。

那么是否可以用不同的方式编写它:

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

如果我使用一个简单的值,(a+b)/2我会得到null其中一个值是null.

4

4 回答 4

4

可能最简单的方法是使用outer applywithavg()因为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方法还是比较简单的。

于 2016-12-19T14:16:53.350 回答
3

假设它们都null应该产生null平均值的情况,您可以使用数学“技巧”(A+A)/2=A并使用coalesce以非常优雅的方式编写此代码,恕我直言:

(COALESCE(a, b) + COALESCE(b, a)) / 2
于 2016-12-19T14:17:25.573 回答
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   |
+----+------+------+--------+
于 2016-12-19T14:25:28.903 回答
0

尝试以下操作:

SELECT (ISNULL(a, b)+ISNULL(b, a))/2
于 2016-12-19T14:18:42.040 回答