Description
Table: Numbers
| Column Name | Type |
|---|---|
| num | int |
| frequency | int |
numis the primary key (column with unique values) for this table.- Each row of this table shows the frequency of a number in the database.
The median is the value separating the higher half from the lower half of a data sample.
Problem Statement
Write a solution to report the median of all the numbers in the database after decompressing the Numbers table. Round the median to one decimal point.
The result format is in the following example.
Example 1:
Input:
Numberstable:
| num | frequency |
|---|---|
| 0 | 7 |
| 1 | 1 |
| 2 | 3 |
| 3 | 1 |
Output:
| median |
|---|
| 0.0 |
Explanation:
If we decompress the Numbers table, we will get [0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3], so the median is (0 + 0) / 2 = 0.
Solution
In this case, we will have total of 12 numbers if they are inserted frequency number of times. So, median record is at index position 6 and 7.
- First, you need to find the position of the median number based on frequency. This you can find using sum of frequency divided by 2. That will be the position of the median number.
1SELECT num, frequency,
2 (SUM(frequency) OVER ()) / 2 AS 'median_position'
3 FROM Numbers
| num | frequency | median_num |
|---|---|---|
| 0 | 7 | 6 |
| 1 | 1 | 6 |
| 2 | 3 | 6 |
| 3 | 1 | 6 |
As you can see from above, we have found the median_position, that is the record number from this table that contains median value.
- You also need to find what will be the position of each number if they were inserted
frequencynumber of times in the array. This can be done using the running sum of frequency ordered by number.
1SELECT num, frequency,
2 SUM(frequency) OVER (ORDER BY num) AS running_position
3 FROM Numbers;
| num | frequency | running_position |
|---|---|---|
| 0 | 7 | 7 |
| 1 | 1 | 8 |
| 2 | 3 | 11 |
| 3 | 1 | 12 |
This gives us the position for each number in the inpute table.
- Now to find the median number, you have to find number which is having
running_position - frequencyandrunning_position.
1WITH cte AS (
2 SELECT num, frequency,
3 SUM(frequency) OVER (ORDER BY num) running_position,
4 (SUM(frequency) OVER ()) / 2 AS median_position
5 FROM Numbers
6) SELECT AVG(num) AS median
7 FROM cte
8 WHERE median_position BETWEEN (running_position - frequency)
9 AND running_position;


Comments