我有一张有5列的表格。我需要为每一行使用SQL找到平均值(忽略0列)。我可以得到一些帮助。
COL1 COL2 COL3 COL4 COL5 AVERAGE
1 2 3 4 5 3
4 0 4 0 4 4
3 0 0 0 9 6
7 0 0 0 0 7
对不起桌子没说清楚。我需要为每一行计算任何非零值的平均值。例如:5个cols有(4,0,4,0,4)我不需要12/5的平均值,我需要平均值为12/3 = 4。基本上除以非零值的数量。它并不总是除以5
答案 0 :(得分:2)
这比第一眼看上去有点棘手。如果不使用数据透视表(这是另一种方法,但这里可能有点过分),您可以对列进行求和,然后除以非零列的数量。诀窍是当每一列都为零时,你需要特别满足这一要求,否则你会得到除以零的错误:
SELECT
COL1, COL2, COL3, COL4, COL5,
CASE WHEN (COL1 = 0 AND COL2 = 0 AND COL3 = 0 AND COL4 = 0 AND COL5 = 0)
THEN 0
ELSE
(COL1 + COL2 + COL3 + COL4 + COL5)
/ (
CASE WHEN COL1 = 0 THEN 0 ELSE 1 END +
CASE WHEN COL2 = 0 THEN 0 ELSE 1 END +
CASE WHEN COL3 = 0 THEN 0 ELSE 1 END +
CASE WHEN COL4 = 0 THEN 0 ELSE 1 END +
CASE WHEN COL5 = 0 THEN 0 ELSE 1 END
)
END AS AVERAGE
FROM stats
答案 1 :(得分:1)
以下是使用CROSS APPLY
的另一个选项。计算平均值时,您必须小心谨慎。例如,您对值1,1,2,2,3的预期平均值是多少? AVG
将返回1,但如果您希望它为1.8,则应在计算平均值之前使用浮点数据类型
with cte as (
select * from
(values
(1, 2, 3, 4, 5)
,(4, 0, 4, 0, 4)
,(3, 0, 0, 0, 9)
,(7, 0, 0, 0, 0)
,(1, 1, 2, 2, 3)
) t(COL1, COL2, COL3, COL4, COL5)
)
select
*
from
cte
cross apply (
select
average = avg(val) --change to avg(val * 1.0) to get floating point numeric
from
(values (COL1), (COL2), (COL3), (COL4), (COL5)) t(val)
where val > 0
) q