丢弃异常值后在 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:平均值、几何平均值、去除异常值、中值