Moyenne tronquée sur la colonne calculée (moy)

Je prends le nombre moyen de minutes entre deux champs de date – de xreports dans les 5 derniers jours – cela fonctionne bien:

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

Cependant, il y a beaucoup de valeurs aberrantes biaisant cette moyenne, donc je voudrais prendre la gamme interquartile – c'est-à-dire perdre le haut et le bas de 25%.

J'ai trouvé cet article .

Ceci explique comment le faire sur une vraie colonne, mais je ne peux pas l'get pour travailler avec Avg () de la différence entre 2 colonnes – c'est le meilleur que je peux faire:

 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) 

Cependant, la colonne "avd" n'est pas reconnue.

Comment puis-je faire ceci?

THX.

Une façon serait d'utiliser les fonctions de la window. Ici row_number et count font le travail de comptabiliser le pourcentage correct pour une ligne dans un jeu de résultats fourni.

 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 

Vous pouvez utiliser d'autres fonctions de window, mais je trouve cela plus clair pour les users non expérimentés.

J'inclus * 1.0 pour que la division renvoie des numbers fractionnaires pour un calcul correct des pourcentages.

Ce n'est pas le moyen de le faire dans SQL Server 2016. Voici une méthode:

 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; 

D'autres fonctions de window telles que ntile() et percentile() peuvent également être utilisées. Cette approche de comptage explicite semble la plus proche de ce qui est dans votre question.