Field note · September 18, 2024

The overall average hides 4 different numbers

Real group means for one column across 4 segments, and what the pooled average conceals.

1 min read ·Analytics practice ·statistics practice

region splits saas-subscriptions into 4 groups. Here is what mrr_usd looks like inside each.

  • LATAM — mean 501, median 99 (167 rows)
  • EMEA — mean 486, median 102 (744 rows)
  • AMER — mean 426, median 84 (1,162 rows)
  • APAC — mean 412, median 78 (427 rows)

Top to bottom that is 501 against 412, a spread of 21.5%. The pooled average is 447.

sql
select region,
  count(*)                                             as rows,
  round(avg(mrr_usd)::numeric, 2)                      as mean,
  percentile_cont(0.5) within group (order by mrr_usd) as median
from saas_subscriptions
group by 1
order by mean desc;

The groups are close enough that the pooled average is a fair summary. That is worth confirming rather than assuming: the check costs one query and the failure mode is invisible.

Notice the mean and median columns disagree most in LATAM, where the mean sits well above the median. Always compute both in the group-by. The comparison between them per segment is free and tells you whether you are looking at a level difference or a tail difference.

This is the setup for Simpson's paradox — the case where every segment moves one way and the total moves the other.