计算(平均)列的修剪平均值

Trimmed mean on computed (avg) column

我正在计算两个日期字段之间的平均分钟数 - 最近 5 天的 xreports - 这很有效:

select avg(datediff(minute, findDateTime, reportClosedDateTime)) as avd from xreports 
where findDateTime > dateadd(day, -5, getdate())

但是,有很多异常值扭曲了这个平均值,所以我想采用四分位间距 - 即失去顶部和底部的 25%。

我找到了这个 article

这解释了如何在真实列上执行此操作,但我无法使用 Avg() 处理两列之间的差异 - 这是我能做的最好的:

declare @pp float 
set @pp = .25 

select avg(datediff(minute, findDateTime, reportClosedDateTime)) as avd 
from xreports xr
where findDateTime > dateadd(day, -5, getdate())
and 
    (select count(*) from xReports xr1
        where xr1.finddatetime <= xr.finddatetime) >= 
            (select @pp*count(*) from xReports) 
    and 
    (select count(*) from xReports xr2
        where xr2.avd >= xr.avd) >= 
            (select @pp*count(*) from xReports)

但是,无法识别列 "avd"。

我该怎么做?

谢谢。

这不是在 SQL Server 2016 中执行此操作的方法。这是一种方法:

select avg(datediff(minute, xr.findDateTime, xr.reportClosedDateTime))
from (select xr.*,
             row_number() over (order by datediff(minute, xr.findDateTime, xr.reportClosedDateTime)) as seqnum,
             count(*) over () as cnt
      from xreports xr
     ) xr
where seqnum >= cnt * 0.25 and
      seqnum <= cnt * 0.75;

也可以使用其他window函数,例如ntile()percentile()。这种明确的计数方法似乎最接近您的问题。

一种方法是使用 window 函数。这里 row_numbercount 负责计算提供的结果集中一行的正确百分比。

select avg(datediff(minute, findDateTime, reportClosedDateTime)) as avd
from (
  select
    *, 
    row_number() over (order by datediff(minute, findDateTime, reportClosedDateTime)) * 1.0 / count(*) over () as pn
  from xreports
  where findDateTime > dateadd(day, -5, getdate())
  ) t
where pn > 0.25 and pn < 0.75

您可以使用其他 window 函数,但我发现这对于没有经验的用户来说更清楚。

我将 * 1.0 包括在内以进行除法 return 小数位数,以便正确计算百分比。