Want to make data analysis fast for everyone?Join Us!
avg price of an order in your purchases table is easy. But what about the
median price? Medians are much more difficult for the database to compute, so there usually isn’t a built-in function like the following:
Why is Median Hard?
For the standard aggregate functions (
count, etc.) it’s possible to get the result in a single pass over the data, storing the current
count along the way. If the column is indexed, the minimum or maximum value can be found without looking at any rows!
Median cannot work like that because it’s algorithmically much more complicated. The median is the middle value. The data needs to be sorted so that the middle record can be found.
Finding the Median with Different Databases
Since median is harder than
count and not a standard aggregate function, we’ll need to do a little more work to calculate it. Here’s how on several different databases:
Median on Redshift
The Redshift team recently released a
median window function, making it one of the easiest syntaxes to find the median with:
limit 1: Since
median is a window function and not an aggregate function, it’ll return one value for each row in the table.
Median on Postgres
If you like defining your own functions in Postgres, the Postgres Wiki has a definition for
median. We’ll do it in SQL and get Postgres to help us find the middle value by numbering all the rows with the
row_number() window function.
First, a CTE to sort and number all of the rows, with a
count that’ll help later on:
Then we find the middle one or two rows and average their values:
where clause ensures that we’ll get the two middle values if there is an even number of values, and the single middle number if there is an odd number of values because
between is inclusive of its bounds.
Median on MySQL
MySQL might not have window functions, but it does have variables, and we’ll use them to achieve the same result.
First we’ll set two variables, one for the row count and one to act as the
row_id from before:
And just like before, we average the middle one or two values:
@row_id := @row_id + 1 syntax simply increments the
@row_id counter for each row. Unlike Postgres we don’t need to build up a temporary result set of rows with
row_id because variables let us compute the
row_id on the fly.
Bonus Round: Mode
No post with
median is complete without
mode (defined as the most frequent value) of a column can be found with a simple group and count:
This query gives us the
price with the greatest
count() in the table, also known as the mode.
And now you know how to compute median in SQL for Redshift, Postgres and MySQL databases!