2015-03-24 4 views
0

Например у меня есть следующий список вызовов:Средняя продолжительность первых 80% записей

  • вызов # 1 - продолжительность 30 мин
  • вызов # 2 - продолжительность 43 мин
  • вызов # 3 - длительность 26 мин
  • вызовов # 4 - длительность 35 мин
  • вызова # 5 - длительность 39 мин

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)?

ответ

3

Функция 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 

Это выбирает первый 80% строк в порядке возрастания столбца DURATION, но там, где привязаны записи, принимающие все из них. Используйте only вместо with ties, чтобы вернуть только указанный процент.

Есть много вариантов, которые this blog post также объясняет довольно хорошо.


Для разработки какого процента вызовов будет иметь среднюю продолжительность звонка 30 минут вы должны знать, скользящее среднее, текущий счет, а общее количество строк в таблице. Для скользящего среднего аналитических 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 
+0

А как насчет наоборот? Как рассчитать процент первых вызовов, которые попадают в заданную среднюю продолжительность? Этого нельзя достичь с помощью функции NTILE. – sbrbot

+0

Я не видел этого @sbrbot; Я обновил свой ответ. – Ben

+0

Спасибо @Ben много. Я принял ваш ответ как полный, но могу ли я задать еще одну вещь (если вы можете добавить к предыдущему ответу) - как выбрать длительность 80% -ной записи (например, если есть 500 записей, как получить продолжительность 400-й записи). – sbrbot