我有一张这样的桌子:
|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)
但这只给我一个价值。我没有主意,面临一个非常紧迫的截止日期,因此我们将不胜感激。
答案 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)
我将apply
与avg()
一起使用:
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
表达式。