代码之家  ›  专栏  ›  技术社区  ›  Cade Roux

剔除异常值后在SQL中取平均值

  •  0
  • Cade Roux  · 技术社区  · 15 年前

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

    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
    

    现在我可以过滤掉这一点来消除以前几个月的运行,所以一个进程的平均性能只能在过去3个月内得到,比如说。

    当由于性能或调试不好而出现异常值时,问题就出现了,进程在0秒内完成。

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

    VAR() STDEV() 聚合函数有效吗?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Bill Karwin    15 年前

    聚合函数忽略NULL(除了 COUNT(*) )所以如果你能在表达式中将离群值转换为NULL,那会很有帮助。

    AVG( CASE WHEN Start.EventTime = Finish.EventTime THEN NULL
         ELSE DATEDIFF(SECOND, Start.EventTime, Finish.EventTime) 
         END CASE )
    
        2
  •  0
  •   Ben Schwehn    15 年前

    • 将您的查询转换为一个表变量(或tentable)
    • 此度量可能只是删除低于或高于固定阈值的所有值
    • 和/或首先计算平均值和标准偏差,然后从平均值中删除超过x标准偏差的所有条目
    • 然后对清洗后的产品做进一步的分析