扔掉异常值后在SQL中取平均值

时间:2009-06-09 23:08:33

标签: sql-server tsql statistics aggregate-functions

我有一个通用的日志表,我可以附加到进程及其结果。我使用流程性能视图获得平均时间:

WITH    Events
          AS (
              SELECT    PR.DATA_DT_ID
                       ,P.ProcessID
                       ,P.ProcessName
                       ,PL.GUID
                       ,PL.EventText
                       ,PL.EventTime
              FROM      MISProcess.ProcessResults AS PR
              INNER JOIN MISProcess.ProcessResultTypes AS PRT
                        ON PRT.ResultTypeID = PR.ResultTypeID
                           AND PRT.IsCompleteForTiming = 1
              INNER JOIN MISProcess.Process AS P
                        ON P.ProcessID = PR.ProcessID
              INNER JOIN MISProcess.ProcessLog AS PL
                        ON PL.BatchRunID = PR.BatchRunID
                           AND PL.ProcessID = P.ProcessID
                           AND [GUID] IS NOT NULL
                           AND (
                                PL.EventText LIKE 'Process Starting:%'
                                OR PL.EventText LIKE 'Process Complete:%'
                               )
             )
SELECT  Start.DATA_DT_ID
       ,Start.ProcessName
       ,AVG(DATEDIFF(SECOND, Start.EventTime, Finish.EventTime)) AS AvgDurationSeconds
       ,COUNT(*) AS NumRuns
FROM    Events AS Start
INNER JOIN Events AS Finish
        ON Start.EventText LIKE 'Process Starting:%'
           AND Finish.EventText LIKE 'Process Complete:%'
           AND Start.DATA_DT_ID = Finish.DATA_DT_ID
           AND Start.ProcessID = Finish.ProcessID
           AND Start.GUID = Finish.GUID
GROUP BY Start.DATA_DT_ID
       ,Start.ProcessName

GUID将开始和结束条目与其他“注释”式条目链接起来。

现在我可以对此进行过滤以消除过去几个月的运行,因此,过程的平均性能只能在过去3个月内进行,比如说。

当由于性能不佳或调试而导致异常值时,问题就出现了,其中该过程在0秒或其他任何时间内完成。

我想以某种方式自动消除任何异常值。

VAR()STDEV()汇总功能是否有效?

2 个答案:

答案 0 :(得分:3)

聚合函数忽略NULL(COUNT(*)除外),所以如果你可以在表达式中将异常值转换为NULL,那会有所帮助。

AVG( CASE WHEN Start.EventTime = Finish.EventTime THEN NULL
     ELSE DATEDIFF(SECOND, Start.EventTime, Finish.EventTime) 
     END CASE )

答案 1 :(得分:0)

如果没有详细解析您的查询,我的第一个想法是:

  • 查询表变量(或temptable)
  • 使用您用于定义离群值的任何指标从表中删除异常值
  • 此指标可能只是删除低于或高于固定阈值的所有值
  • 和/或首先计算mean和stdev,然后删除超过x stdev的所有条目
  • 然后对清洁后的临时表进行进一步分析