Oracle PERCENTILE_DISC Function

Get percentiles that are actual values from the data with PERCENTILE_DISC, and see how they differ from interpolated PERCENTILE_CONT.

Sometimes a percentile must be an actual value from the data: a real fare that customers paid, a real response time that occurred, a salary someone earns. PERCENTILE_DISC returns the first value whose cumulative distribution reaches the percentile, so the answer always exists in the group, unlike the interpolated result of PERCENTILE_CONT.

Code for This Guide

The main examples are in the examples/aggregate-functions folder of the Oracle Database 26ai code repository on GitHub, each with its output. They use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.

They come from Oracle Database 26ai SQL and PL/SQL Book.

Syntax

Syntax:

percentile_disc(p) within group (order by expr [asc | desc])

p is a fraction from 0 to 1. The values are ordered by WITHIN GROUP, and PERCENTILE_DISC returns the first one whose cumulative distribution is at least p.

Discrete Percentiles of Bookings

Example:

select percentile_cont(0.5) within group (order by total_amount) as median_cont,
       percentile_disc(0.5) within group (order by total_amount) as median_disc,
       percentile_cont(0.9) within group (order by total_amount) as p90,
       percentile_disc(0.9) within group (order by total_amount desc) as p10_desc
from   bookings
where  status <> 'CANCELLED';

Output:

   MEDIAN_CONT    MEDIAN_DISC        P90    P10_DESC
______________ ______________ __________ ___________
       1001.29        1001.29    3634.11      315.17

Here the discrete and continuous medians happen to be equal. The last column orders descending: the 90th percentile from the top is the 10th percentile from the bottom, 315.17.

Discrete Compared with Continuous

Example:

-- on four values, the median falls between two of them
select percentile_cont(0.5) within group (order by v) as cont_median,
       percentile_disc(0.5) within group (order by v) as disc_median,
       percentile_cont(0.25) within group (order by v) as cont_q1,
       percentile_disc(0.25) within group (order by v) as disc_q1
from   (values (10), (20), (30), (40)) t (v);

Output:

   CONT_MEDIAN    DISC_MEDIAN    CONT_Q1    DISC_Q1
______________ ______________ __________ __________
            25             20       17.5         10

For 10, 20, 30, and 40, PERCENTILE_DISC(0.5) returns 20, the first value at or above the 50 percent mark, where PERCENTILE_CONT interpolates 25.

Per Group

Example:

-- the 90th percentile of fares in each cabin
select cabin, percentile_cont(0.9) within group (order by fare) as p90_fare,
       percentile_disc(0.9) within group (order by fare) as p90_existing_fare
from   tickets
group  by cabin;

Output:

CABIN          P90_FARE    P90_EXISTING_FARE
___________ ___________ ____________________
BUSINESS       4671.295                 4671
ECONOMY        1225.004              1230.62

The discrete 90th percentile of economy fares is 1,230.62, a fare actually paid, slightly above the interpolated 1,225.004.

Things to Know

  • PERCENTILE_DISC works on any sortable type, including dates and text, since it never interpolates.
  • For large groups, the two functions give nearly the same numbers; the difference matters most for small groups.
  • It also works as an analytic function with OVER (PARTITION BY ...).

Related Guides

Conclusion

PERCENTILE_DISC returns an existing value at a percentile of a group: the first whose cumulative distribution reaches it. Use it when the answer must be a real data point, and PERCENTILE_CONT when an interpolated value is acceptable.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted