Problems / Power Users by Percentile Cutoff / Editorial
GROUP BY user_id
COUNT(*)
PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY event_count)
quantile(0.9)
CROSS JOIN
event_count >= p90
'power'
user_id
In PySpark/SQLFrame there is no F.percentile_cont function object; F.expr("percentile_cont(0.9) within group (order by event_count)") inside .agg() passes the ordered-set aggregate through to DuckDB, and .crossJoin attaches the scalar to every row.
F.percentile_cont
F.expr("percentile_cont(0.9) within group (order by event_count)")
.agg()
.crossJoin
This is the *cutoff* flavor of percentile logic, distinct from percent_rank(): instead of scoring every row relative to the others, you reduce the distribution to one threshold value and classify against it. That two-grain shape (aggregate → scalar → rejoin) is the standard way to compare rows against a global statistic, and it generalizes to any "top X% by volume" segmentation. The boundary detail matters: percentile cutoffs are conventionally inclusive, and ties around the threshold (this data has duplicate counts throughout) mean >= vs > changes who gets the power-user badge.
percent_rank()
>=
>
Solve Power Users by Percentile Cutoff yourself →