计算(平均)列

时间:2017-06-23 18:24:41

标签: sql sql-server tsql sql-server-2016

我正在考虑两个日期字段之间的平均分钟数 - 过去5天内的xreports - 这很有效:

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

然而,有许多异常值偏离这个平均值,所以我想采取四分位数范围 - 即失去25%的顶部和底部。

我发现了article

这解释了如何在真正的专栏上进行,但是我不能使用Avg()来处理2列之间的差异 - 这是我能做的最好的事情:

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)

然而,专栏&#34; avd&#34;不被认可。

我该怎么做?

THX。

2 个答案:

答案 0 :(得分:2)

一种方法是使用窗口函数。这里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

您可以使用其他窗口功能,但我发现对于没有经验的用户来说更清楚。

我包括* 1.0以使分割返回小数位数以正确计算百分比。

答案 1 :(得分:0)

这不是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;

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