SQL。调用PERCENTILE_CONT函数的意外结果

时间:2016-06-06 13:35:08

标签: sql oracle statistics

实际上我已经理解了PERCENTILE_CONT是如何工作的,但是通过手工计算百分位数和调用函数我得到了不同的结果。 这是数据集:

305.7884804
350
373.3728865
384.2094838
410.8603441
414.9842786
455.3545205
550

要计算25%,我总结350373.3728865,然后将其除以2.结果为361.68644325

要计算50%,我总结384.2094838410.8603441,然后将其除以2.结果为397.53491395

要计算75%,我总结414.9842786455.3545205,然后将其除以2.结果为435.16939955

然而,当我运行这个sql:

select 
percentile_cont(0.25) within group(order by YEAR_2_FTE ASC), 
percentile_cont(0.5) within group(order by YEAR_2_FTE ASC), 
percentile_cont(0.75) within group(order by YEAR_2_FTE ASC) from sr_database 
where firm_id=999;

我得到了这样的结果:

25%: 367.529664875
50%:397.53491395
75%:425.076839075

我错过了什么?

1 个答案:

答案 0 :(得分:4)

你正确地在第4和第5个值之间取得了这一点来计算第50个百分点。但是,对于第25个百分位数而言,在第2个和第3个之间取得中间点(同样对于第75个百分点)并不正确。最好看一下插图:

enter image description here

这显示了它们之间绘制的8个点和4个线,以制作4个大小相等的段。第25和第75百分位标记分别接近第3和第6个值。

Oracle documentation描述了如何计算这些内容:

  

PERCENTILE_CONT的结果通过线性插值计算   订购后的价值之间。使用百分位值(P)和   在聚合组中的行数(N),我们计算行   在订购相关的行之后我们感兴趣的数字   排序规范。根据行计算该行号(RN)   公式RN =(1+(P *(N-1))。汇总的最终结果   函数是通过值之间的线性插值计算的   行号CRN = CEILING(RN)和FRN = FLOOR(RN)。

在您的示例中,对于第25个百分位P = 0.25N = 8,所以:

RN = (1+ 0.25*(8-1))
   = 2.75

所以CRN = 3FRN = 2

文档继续说:

  

最终结果将是:

     

如果(CRN = FRN = RN)则结果为

(value of expression from row at RN)
     

否则结果是

(CRN - RN) * (value of expression for row at FRN) +

(RN - FRN) * (value of expression for row at CRN)

插入上面的值,"否则......"部分适用于计算,即:

Result = (3 - 2.75) * 350 + (2.75 - 2) * 373.3728856
       = 367.5296642

同样的第75百分位:

 RN = (1+ 0.75*(8-1))
    = 6.25
CRN = 7
FRN = 6
Result = (7 - 6.25) * 414.9842786 + (6.25 - 6) * 455.3545205
       = 425.076839075