丢弃异常值后在 SQL 中取平均值

Posted

技术标签:

【中文标题】丢弃异常值后在 SQL 中取平均值【英文标题】:Taking an average in SQL after throwing away outliers 【发布时间】:2010-11-01 15:47:53 【问题描述】:

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

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() 聚合函数会起作用吗?

【问题讨论】:

这里的问题是自动定义什么是“异常值”,这主要是一个统计问题。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

任何不经意的观察者的注意事项:Count(field_name) 将忽略 NULL。

以上是关于丢弃异常值后在 SQL 中取平均值的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery SQL:平均值、几何平均值、去除异常值、中值

嵌入函数返回值后在函数中调用completionHandler?迅速

如何获取在CoreData中取平均值的Entity属性

填写值后在输入文本框时未触发提交。在 IE 中

剔除“异常值”的一般原则是什么?

oracle 取平均值