Аналитический Скользящий Процентиль Oracle
можно ли использовать windowing с любой из функций процентиля? Или вы знаете способ получить значение перцентиль?
это легко с перемещением в среднем:
select avg(foo) over (order by foo_date rows
between 20 preceding and 1 preceding) foo_avg_ma
from foo_tab
но я не могу понять, как получить в среднем (50% процентиль) над тем же окном.
1 ответов
можно использовать функция percentile_cont или PERCENTILE_DISC функция для поиска медианы.
PERCENTILE_CONT-это функция обратного распределения, которая предполагает модель непрерывного распределения. Он принимает значение процентиля и сортировку спецификация, и возвращает интерполированное значение, которое будет попадать в это значение процентиля по отношению к спецификации сортировки. Значение null игнорируются в расчет.
...
PERCENTILE_DISC-это функция обратного распределения, которая предполагает дискретная модель распределения. Он принимает значение процентиля и сортировку спецификация и возвращает элемент из набора. Нули игнорируются в расчет.
...
в следующем примере вычисляется медианная зарплата в каждом отделе:
SELECT department_id, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary DESC) "Median cont", PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY salary DESC) "Median disc" FROM employees GROUP BY department_id ORDER BY department_id;
...
PERCENTILE_CONT и PERCENTILE_DISC могут возвращать разные результаты. PERCENTILE_CONT возвращает вычисленный результат после выполнения линейного интерполяция. PERCENTILE_DISC просто возвращает значение из набора значения, которые агрегируются. Когда значение процентиля равно 0,5, как в этом примере PERCENTILE_CONT возвращает среднее значение двух средних значения для групп с четным числом элементов, тогда как PERCENTILE_DISC возвращает значение первого из двух среднее значение. Для агрегатных групп с нечетным числом элементов, обе функции возвращают значение среднего элемента.
образец с окном моделирования корыта диапазон self-join
with sample_data as (
select /*+materialize*/ora_hash(owner) as table_key,object_name,
row_number() over (partition by owner order by object_name) as median_order,
row_number() over (partition by owner order by dbms_random.value) as any_window_sort_criteria
from dba_objects
)
select table_key,x.any_window_sort_criteria,x.median_order,
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY y.median_order DESC) as rolling_median,
listagg(to_char(y.median_order), ',' )WITHIN GROUP (ORDER BY y.median_order) as elements
from sample_data x
join sample_data y using (table_key)
where y.any_window_sort_criteria between x.any_window_sort_criteria-3 and x.any_window_sort_criteria+3
group by table_key,x.any_window_sort_criteria,x.median_order
order by table_key, any_window_sort_criteria
/