|
| 1 | +--- |
| 2 | +title: percentileif |
| 3 | +description: 'This page explains how to use the percentileif aggregation function in APL.' |
| 4 | +--- |
| 5 | + |
| 6 | +The `percentileif` aggregation function calculates the percentile of a numeric column, conditional on a specified boolean predicate. This function is useful for filtering data dynamically and determining percentile values based only on relevant subsets of data. |
| 7 | + |
| 8 | +You can use `percentileif` to gain insights in various scenarios, such as: |
| 9 | + |
| 10 | +- Identifying response time percentiles for HTTP requests from specific regions. |
| 11 | +- Calculating percentiles of span durations for specific service types in OpenTelemetry traces. |
| 12 | +- Analyzing security events by percentile within defined risk categories. |
| 13 | + |
| 14 | +## For users of other query languages |
| 15 | + |
| 16 | +If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL. |
| 17 | + |
| 18 | +<AccordionGroup> |
| 19 | +<Accordion title="Splunk SPL users"> |
| 20 | + |
| 21 | +The `percentileif` aggregation in APL works similarly to `percentile` combined with conditional filtering in SPL. However, APL integrates the condition directly into the aggregation for simplicity. |
| 22 | + |
| 23 | +<CodeGroup> |
| 24 | +```sql Splunk example |
| 25 | +stats perc95(req_duration_ms) as p95 where geo.country="US" |
| 26 | +``` |
| 27 | + |
| 28 | +```kusto APL equivalent |
| 29 | +['sample-http-logs'] |
| 30 | +| summarize percentileif(req_duration_ms, 95, geo.country == 'US') |
| 31 | +``` |
| 32 | +</CodeGroup> |
| 33 | + |
| 34 | +</Accordion> |
| 35 | +<Accordion title="ANSI SQL users"> |
| 36 | + |
| 37 | +In SQL, you typically calculate percentiles using window functions or aggregate functions combined with a `WHERE` clause. APL simplifies this by embedding the condition directly in the `percentileif` aggregation. |
| 38 | + |
| 39 | +<CodeGroup> |
| 40 | +```sql SQL example |
| 41 | +SELECT PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY req_duration_ms) |
| 42 | +FROM sample_http_logs |
| 43 | +WHERE geo_country = 'US' |
| 44 | +``` |
| 45 | + |
| 46 | +```kusto APL equivalent |
| 47 | +['sample-http-logs'] |
| 48 | +| summarize percentileif(req_duration_ms, 95, geo.country == 'US') |
| 49 | +``` |
| 50 | +</CodeGroup> |
| 51 | + |
| 52 | +</Accordion> |
| 53 | +</AccordionGroup> |
| 54 | + |
| 55 | +## Usage |
| 56 | + |
| 57 | +### Syntax |
| 58 | + |
| 59 | +```kusto |
| 60 | +summarize percentileif(Field, Percentile, Predicate) |
| 61 | +``` |
| 62 | + |
| 63 | +### Parameters |
| 64 | + |
| 65 | +| Parameter | Description | |
| 66 | +|------------------|--------------------------------------------------------------------------------------------------------------| |
| 67 | +| `Field` | The numeric field from which to calculate the percentile. | |
| 68 | +| `Percentile` | A number between 0 and 100 that specifies the percentile to calculate. | |
| 69 | +| `Predicate` | A Boolean expression that filters rows to include in the calculation. | |
| 70 | + |
| 71 | +### Returns |
| 72 | + |
| 73 | +The function returns a single numeric value representing the specified percentile of the `Field` for rows where the `Predicate` evaluates to `true`. |
| 74 | + |
| 75 | +## Use case examples |
| 76 | + |
| 77 | +<Tabs> |
| 78 | +<Tab title="Log analysis"> |
| 79 | + |
| 80 | +You can use `percentileif` to analyze request durations for specific HTTP methods. |
| 81 | + |
| 82 | +**Query** |
| 83 | + |
| 84 | +```kusto |
| 85 | +['sample-http-logs'] |
| 86 | +| summarize post_p90 = percentileif(req_duration_ms, 90, method == "POST"), get_p90 = percentileif(req_duration_ms, 90, method == "GET") by bin_auto(_time) |
| 87 | +``` |
| 88 | + |
| 89 | +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/explorer?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20summarize%20post_p90%20%3D%20percentileif(req_duration_ms%2C%2090%2C%20method%20%3D%3D%20'POST')%2C%20get_p90%20%3D%20percentileif(req_duration_ms%2C%2090%2C%20method%20%3D%3D%20'GET')%20by%20bin_auto(_time)%22%7D) |
| 90 | + |
| 91 | +**Output** |
| 92 | + |
| 93 | +| post_p90 | get_p90 | |
| 94 | +|--------------|---| |
| 95 | +| 1.691 ms | 1.453 ms | |
| 96 | + |
| 97 | +This query calculates the 90th percentile of request durations for HTTP POST and GET methods. |
| 98 | + |
| 99 | +</Tab> |
| 100 | +<Tab title="OpenTelemetry traces"> |
| 101 | + |
| 102 | +You can use `percentileif` to measure span durations for specific services and operation kinds. |
| 103 | + |
| 104 | +**Query** |
| 105 | + |
| 106 | +```kusto |
| 107 | +['otel-demo-traces'] |
| 108 | +| summarize percentileif(duration, 95, ['service.name'] == 'frontend' and kind == 'server') |
| 109 | +``` |
| 110 | + |
| 111 | +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/explorer?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D%20%7C%20summarize%20percentileif%28duration%2C%2095%2C%20%5B%27service.name%27%5D%20%3D%3D%20%27frontend%27%20and%20kind%20%3D%3D%20%27server%27%29%22%7D) |
| 112 | + |
| 113 | +**Output** |
| 114 | + |
| 115 | +| Percentile95 | |
| 116 | +|---------------| |
| 117 | +| 1.2s | |
| 118 | + |
| 119 | +This query calculates the 95th percentile of span durations for server spans in the `frontend` service. |
| 120 | + |
| 121 | +</Tab> |
| 122 | +<Tab title="Security logs"> |
| 123 | + |
| 124 | +You can use `percentileif` to calculate response time percentiles for specific HTTP status codes. |
| 125 | + |
| 126 | +**Query** |
| 127 | + |
| 128 | +```kusto |
| 129 | +['sample-http-logs'] |
| 130 | +| summarize percentileif(req_duration_ms, 75, status == '404') |
| 131 | +``` |
| 132 | + |
| 133 | +[Run in Playground](https://play.axiom.co/axiom-play-qf1k/explorer?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%20%7C%20summarize%20percentileif%28req_duration_ms%2C%2075%2C%20status%20%3D%3D%20%27404%27%29%22%7D) |
| 134 | + |
| 135 | +**Output** |
| 136 | + |
| 137 | +| Percentile75 | |
| 138 | +|--------------| |
| 139 | +| 350 | |
| 140 | + |
| 141 | +This query calculates the 75th percentile of request durations for HTTP 404 errors. |
| 142 | + |
| 143 | +</Tab> |
| 144 | +</Tabs> |
| 145 | + |
| 146 | +## List of related aggregations |
| 147 | + |
| 148 | +- [percentile](/apl/aggregation-function/percentile): Calculates the percentile for all rows without any filtering. Use `percentile` when you don’t need conditional filtering. |
| 149 | +- [avgif](/apl/aggregation-function/avgif): Calculates the average of a numeric column based on a condition. Use `avgif` for mean calculations instead of percentiles. |
| 150 | +- [minif](/apl/aggregation-function/minif): Returns the minimum value of a numeric column where a condition is true. Use `minif` for identifying the lowest values within subsets. |
| 151 | +- [maxif](/apl/aggregation-function/maxif): Returns the maximum value of a numeric column where a condition is true. Use `maxif` for identifying the highest values within subsets. |
| 152 | +- [sumif](/apl/aggregation-function/sumif): Sums a numeric column based on a condition. Use `sumif` for conditional total calculations. |
0 commit comments