2017-06-23 285 views
2

我拿着两个日期字段之间的平均分钟数 - 在最近5天xreports - 这工作得很好:尾均值的计算(平均)列

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

然而,也有不少离群歪斜这个平均值,所以我想采用四分位数范围 - 即失去最高和最低的25%。我发现这个article

解释如何做一个真正的列,但我不能得到它的2列之间有区别的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”列未被识别。

我该怎么做?

thx。

+0

无法识别列'avd',因为您无法在同一查询级别中引用别名。把它放在子查询中。无论如何,这个查询有优化空间,但只是给你一个杆。 –

+0

我不太确定该怎么做?你会如何建议优化它? – niico

回答

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以使分部返回小数位以正确计算百分比。

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()也可以使用。这种明确的计数方法似乎最接近你的问题。

+0

无法得到这个工作,但可以与卡米尔G. – niico

+0

这个查询有什么问题吗?没有明显的语法错误。 –

+0

它只是返回null?! – niico