如何使用SqlServer Select获得非空,非0的平均值

时间:2013-10-10 19:51:24

标签: sql-server

  

**注意:我需要更进一步并添加NULLIF(0或5)。我在这里写了一篇关于我答案的简短帖子:   http://peterkellner.net/2013/10/13/creating-a-compound-nullif-in-avg-function-with-sqlserver/   但我对我的解决方案不满意)

我有一张结果表,与会者输入了课程的估计出勤率。如果他们输入0或将其留空,我想忽略它并获得输入的值的平均值。我无法弄清楚如何将该约束添加到我的AVG函数而不需要整个SQL的where子句。那可能吗?我的代码如下所示:( EstimatedNumberAttendees就是我要追求的目标)。

SELECT dbo.SessionEvals.SessionId,
   AVG(Cast (dbo.SessionEvals.CourseAsWhole as Float)) AS CourseAsWholeAvg,
   COUNT(*),
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'On Time' then 1
           else null
         end) AS SpeakerOnTime,
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'Late' then 1
           else null
         end) AS SpeakerLate,
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'NoShow' then 1
           else null
         end) AS SpeakerNoShow,
   COUNT(case
           when dbo.SessionEvals.PercentFull = '10% to 90%' then 1
           else null
         end) AS PercentFull10to90,
   COUNT(case
           when dbo.SessionEvals.PercentFull = '> 90%' then 1
           else null
         end) AS PercentFullGreaterThan90,
   COUNT(case
           when dbo.SessionEvals.PercentFull = ' < 10% Full ' then 1
           else null
         end) AS PercentFullLessThan10,
   AVG(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float)) AS
   EstimatedAttending
FROM dbo.Sessions
 INNER JOIN dbo.SessionEvals ON (dbo.Sessions.Id =
 dbo.SessionEvals.SessionId)
WHERE dbo.Sessions.CodeCampYearId = 8
GROUP BY dbo.SessionEvals.SessionId

3 个答案:

答案 0 :(得分:2)

AVG省略了NULL。因此,将其视为NULL。请使用NULLIF

...
AVG(NULLIF(Cast (dbo.SessionEvals.CourseAsWhole as Float), 0)) AS CourseAsWholeAvg,
...
AVG(NULLIF(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float), 0)) AS EstimatedAttending
...

答案 1 :(得分:0)

您可以尝试使用内部查询来获取相同的会话但排除零和null:

SELECT dbo.SessionEvals.SessionId,
   (
        SELECT AVG(SE1.CourseAsWhole)
        FROM dbo.SessionEvals SE1
        WHERE SE1.SessionId = dbo.SessionEvals.SessionId
        AND ISNULL(SE1.CourseAsWhole, 0) <> 0
   ) AS CourseAsWholeAvg,
   COUNT(*),
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'On Time' then 1
           else null
         end) AS SpeakerOnTime,
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'Late' then 1
           else null
         end) AS SpeakerLate,
   COUNT(case
           when dbo.SessionEvals.InstructorPromptness = 'NoShow' then 1
           else null
         end) AS SpeakerNoShow,
   COUNT(case
           when dbo.SessionEvals.PercentFull = '10% to 90%' then 1
           else null
         end) AS PercentFull10to90,
   COUNT(case
           when dbo.SessionEvals.PercentFull = '> 90%' then 1
           else null
         end) AS PercentFullGreaterThan90,
   COUNT(case
           when dbo.SessionEvals.PercentFull = ' < 10% Full ' then 1
           else null
         end) AS PercentFullLessThan10,
   AVG(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float)) AS
   EstimatedAttending
FROM dbo.Sessions
 INNER JOIN dbo.SessionEvals ON (dbo.Sessions.Id =
 dbo.SessionEvals.SessionId)
WHERE dbo.Sessions.CodeCampYearId = 8
GROUP BY dbo.SessionEvals.SessionId

答案 2 :(得分:0)

默认情况下,SQL AVG函数会忽略空值,因此您只需要排除0。您的AVG代码可以更改为:

AVG(nullif( Cast(dbo.SessionEvals.CourseAsWhole as Float), 0) AS CourseAsWholeAvg