2017-06-23 58 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