简体   繁体   English

每行的SQL平均多列具有空值

[英]SQL average multiple columns for each row with nulls

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. 我知道问题是除数在我的select语句中是硬编码的,但我无法弄清楚如何使它变量。 I tried using a case statement to select an addition column: 我尝试使用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)

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. 我没有想法,面临一个非常紧迫的截止日期,所以任何帮助都会非常感激。

Instead of dividing by 3, use 使用,而不是除以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)

I would use apply instead : 我会用apply代替:

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

I would use apply with avg() : 我会使用avg() apply

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 . 这不需要子查询,不长case表达,很容易推广到更多的列,运行无除以零风险。 . . and the performance might even be equivalent to the case expression. 并且性能甚至可能等同于case表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM