计算(平均)列的修剪平均值
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_number
和 count
负责计算提供的结果集中一行的正确百分比。
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 小数位数,以便正确计算百分比。
我正在计算两个日期字段之间的平均分钟数 - 最近 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_number
和 count
负责计算提供的结果集中一行的正确百分比。
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 小数位数,以便正确计算百分比。