来自同一行的平均值 - SQL服务器

时间:2018-01-21 21:27:38

标签: sql sql-server average

我有一张有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

2 个答案:

答案 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

SQLFiddle

答案 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