SQL平均每行多列为空

时间:2018-06-25 18:02:19

标签: sql sql-server

我有一张这样的桌子:

|Quality|Schedule|Cost Control|
-------------------------------
|7      | 8.5    |10          |
|NULL   | 9      |NULL        |

我需要计算同一张表中每一行的平均值,如下所示:

|Quality|Schedule|Cost Control|AVG|
----------------------------------
|7      | 8.5    |10          |8.5|
|NULL   | 9      |NULL        |9  |

我使用以下代码完成了此操作:

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

哪个提供了下表:

|Quality|Schedule|Cost Control|AVG|
----------------------------------
|7      | 8.5    |10          |8.5|
|NULL   | 9      |NULL        |3  |

我知道问题是除数在我的select语句中进行了硬编码,但是我不知道如何使它可变。我尝试使用case语句选择一个附加列:

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)

但这只给我一个价值。我没有主意,面临一个非常紧迫的截止日期,因此我们将不胜感激。

3 个答案:

答案 0 :(得分:2)

而不是除以3,而是使用

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

答案 1 :(得分:1)

我改用apply

select *, (select sum(v) / count(v) 
           from ( values (quality), (Schedule), (CostControl) 
                ) tt(v) 
          ) as AVG
from table t;

答案 2 :(得分:0)

我将applyavg()一起使用:

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

这不需要子查询,不需要长case表达式,可以很容易地将其推广到更多列,不存在被零除的风险。 。 。而且性能甚至可以等同于case表达式。

相关问题