我想取多列的平均值,以便如果有空值,则忽略该值,而将剩余值作为取平均值。
例如,如果我将10,NULL
作为值,那么我希望将10作为平均值,那么我不希望将空值视为0,然后将平均值作为10 + 0-> 5,我希望平均为10。
这是一个虚拟表,我有多个列,例如Month1...。Month 1000,我不想在除以列数来计算平均值时对任何值进行硬编码。
此查询的输出错误:
CREATE TABLE Dummy_tab
(
empid int,
Month1 int,
Month2 int,
Month3 int,
);
INSERT INTO Dummy_tab
VALUES (1, NULL,10, 20), (2, NULL,NULL, 20), (3, 10,20, 30);
SELECT
empid,
AVG(Month1 + Month2 + Month3)
FROM
Dummy_tab
GROUP BY
empid
所需输出以及我的输出内容的摘要
答案 0 :(得分:3)
一个可能的选择是使用VALUES
表值构造函数-将列取消透视成行并计算所有列的平均值,但不包括具有NULL
值的列:
声明:
SELECT t.empid, c.Average
FROM Dummy_tab t
CROSS APPLY (
SELECT AVG(v.Month) AS Average
FROM (VALUES (t.Month1), (t.Month2), (t.Month3)) v (Month)
) c
结果:
empid Average
1 15
2 20
3 20
答案 1 :(得分:0)
在处理整数和除法时,需要先将分子或分母转换为十进制值。
对于一行中三个值的平均值:
(
或更一般地说,您可以将其应用于具有多行的组。 SELECT
empid,
(
-- coalesce(MonthX, 0) would work too
CASE WHEN Month1 IS NULL THEN 0.0 ELSE Month1 END +
CASE WHEN Month2 IS NULL THEN 0.0 ELSE Month2 END +
CASE WHEN Month3 IS NULL THEN 0.0 ELSE Month3 END +
) * 1.0 /
(
CASE WHEN Month1 IS NULL THEN 0.0 ELSE 1.0 END +
CASE WHEN Month2 IS NULL THEN 0.0 ELSE 1.0 END +
CASE WHEN Month3 IS NULL THEN 0.0 ELSE 1.0 END
) AS Average
FROM
Dummy_tab
GROUP BY
empid;
自动处理空值:
SUM()
答案 2 :(得分:0)
我认为这应该可以完成您要完成的任务:
SELECT
empid,
(SUM(ISNULL(Month1,0))
+ SUM(ISNULL(Month2,0))
+ SUM(ISNULL(Month3,0)))
/
(ISNULL(COUNT(Month1),0)
+ ISNULL(COUNT(Month2),0)
+ ISNULL(COUNT(Month3),0)
)
FROM
Dummy_tab
GROUP BY
empid
答案 3 :(得分:0)
如果纠正他的错字,Shawnt00的代码就可以工作。
SELECT
empid,
SUM(
CASE WHEN Month1 IS NULL THEN 0.0 ELSE Month1 END +
CASE WHEN Month2 IS NULL THEN 0.0 ELSE Month2 END +
CASE WHEN Month3 IS NULL THEN 0.0 ELSE Month3 END
) /
SUM(
CASE WHEN Month1 IS NULL THEN 0.0 ELSE 1.0 END +
CASE WHEN Month2 IS NULL THEN 0.0 ELSE 1.0 END +
CASE WHEN Month3 IS NULL THEN 0.0 ELSE 1.0 END
) AS Average
FROM
Dummy_tab
GROUP BY
empid