SQL · hard · Reported at Airbnb

Calculate the median order value using SQL.

Asked in Data Analyst interviews, in the SQL round.

Short answer

Use PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) where supported.

Sample data

These tables are loaded into an in-browser engine on this page, so you can run your own answer against them. No account needed.

orders

order_idamount
112.5
240
325
490
518
655
733
870
922

How to answer it

Definition

The middle value when the orders are sorted. Unlike an average there is no plain aggregate for it in standard SQL, because it depends on position rather than on a running total.

The direct way

SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS median_order
FROM   orders;

Output

median_order
-------------
       48.50

The portable way

Where PERCENTILE_CONT is unavailable, number the rows from both ends and take the middle. This handles even counts by averaging the two middle values.

WITH ranked AS (
  SELECT amount,
         ROW_NUMBER() OVER (ORDER BY amount)      AS asc_rn,
         ROW_NUMBER() OVER (ORDER BY amount DESC) AS desc_rn
  FROM   orders
)
SELECT AVG(amount) AS median_order
FROM   ranked
WHERE  asc_rn IN (desc_rn, desc_rn - 1, desc_rn + 1);

CONT or DISC

PERCENTILE_CONT interpolates between the two middle values on an even count, so it can return a number nobody was actually charged. PERCENTILE_DISC returns an observed value. For money the interpolated version is the usual choice; for something like "the median plan a customer is on", the discrete one is right.

Key points

FAQ

The 30-second answer

If the engine supports it, PERCENTILE_CONT of zero point five WITHIN GROUP ordered by amount. That is one line and it handles even counts by interpolating.
If not, I would number the rows ascending and descending with two ROW_NUMBERs and average the middle one or two, which is the portable version and gets the even case right. The thing I would raise is why we want a median at all: order values are skewed by a few large orders, so the mean sits above almost every customer while the median describes them. I would also ask whether we want the interpolated median or a real observed order, because those differ on an even count.

In the interview

Practice this for real