Oracle Analytic Rolling Percentile

时间:2012-07-20 15:54:48

标签: oracle oracle11g analytic-functions

是否可以使用任何百分位函数的窗口?或者你知道一个可以获得滚动百分位价值的工作吗?

移动平均值很容易:

select avg(foo) over (order by foo_date rows 
                      between 20 preceding and 1 preceding) foo_avg_ma
from foo_tab

但我无法弄清楚如何在同一个窗口中获得中位数(50%百分位数)。

1 个答案:

答案 0 :(得分:6)

您可以使用PERCENTILE_CONTPERCENTILE_DISC功能查找中位数。

  

PERCENTILE_CONT是一个逆分布函数,假定为   连续分布模型。它需要一个百分位值和一个种类   规范,并返回一个内插值   关于排序规范的百分位值。空值   在计算中被忽略。

...

  

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返回两者中第一个的值   中间价值观。对于具有奇数个元素的聚合组,   这两个函数都返回中间元素的值。

带窗口模拟的SAMPLE范围自连接

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
/

enter image description here