6

是否可以将窗口与任何百分位函数一起使用?或者您知道获得滚动百分位值的解决方法吗?

移动平均线很容易:

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

但我不知道如何在同一个窗口中获得中位数(50% 百分位数)。

4

1 回答 1

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
/

在此处输入图像描述

于 2012-07-22T13:29:35.660 回答