IntermediateWindow Functions

Customer order value percentile ranking

The query

SQL
WITH customer_totals AS (
  SELECT
    c.name,
    c.country,
    SUM(o.total) AS total_spent
  FROM customers c
  JOIN orders o ON c.cust_id = o.cust_id
  WHERE o.status = 'completed'
  GROUP BY c.cust_id, c.name, c.country
)
SELECT
  name,
  country,
  total_spent,
  ROUND(PERCENT_RANK() OVER (ORDER BY total_spent) * 100, 1) AS spend_percentile,
  NTILE(10) OVER (ORDER BY total_spent DESC) AS decile
FROM customer_totals
ORDER BY total_spent DESC;
Tested against PostgreSQL 16

Note

PERCENT_RANK for continuous percentile. NTILE(10) creates deciles. Classic RFM (Recency/Frequency/Monetary) pattern.

Tables referenced