前 80% 记录的平均持续时间

The average duration of first 80% records

例如,我有以下呼叫列表:

1) 我需要 SQL 查询检索 前 80% 的调用 的平均持续时间

前 80% 的呼叫(根据呼叫持续时间)是呼叫 #3、#1、#4、#5。对于这些调用,应计算平均持续时间 ((26+30+35+39)/4=32,5)。超过 80% 的调用(此处调用 #2)应被忽略。

2) 我还需要反之亦然的查询 - 首次通话的平均通话时长为 30 分钟的百分比是多少?

3) 热获取第 80% 条记录持续时间(根据通话持续时间排序)。例如。如果有 500 条记录,第 400 条记录的持续时间是多少?

这个 SQL 查询应该是什么样子 (Oracle)?

NTILE() 函数将数据集拆分为桶;将前 80% 分成 5 份并取前 4 份:

select avg(duration)
  from ( select duration, ntile(5) over (order by duration) as bucket
           from ...
                )
 where bucket <= 4

如果您使用的是 Oracle 12c,那么 row limiting clause 进行了大得离谱的功能升级,您可以获得实际百分比,例如:

select avg(duration)
  from ...
 order by duration
 fetch first 80 percent rows with ties

这会按 DURATION 列升序的顺序选择前 80% 的行,但其中有接受所有这些记录的绑定记录。使用 only 而不是 with ties 仅 return 指定的百分比。

有很多选项,this blog post也解释得很好。


要计算平均通话时长为 30 分钟的通话百分比,您需要知道 运行 平均值、运行 计数和 table。对于 运行 平均值,解析 AVG() 应该有效,解析 COUNT() 用于总行数:

select max(running_count) / max(total_calls)
  from ( select duration
              , count(*) over () as total_calls
              , row_number() over (order by duration) as running_count
              , avg(duration) over (order by duration) as running_avg
           from ...
                )
 where running_avg <= 30