力扣571(MySQL)-给定数字的频率查询中位数(困难)

发布时间 2023-03-26 21:59:47作者: 我不想一直当菜鸟

题目:

Numbers 表保存数字的值及其频率。

 在此表中,数字为 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3,所以中位数是 (0 + 0) / 2 = 0。

 请编写一个查询来查找所有数字的中位数并将结果命名为 median 。

解题思路:

可以借助之前力扣569-员工薪水中位数的题解思路,利用窗口函数对频率分别以正序和逆序方式求和,然后求正序和逆序大于频率总值一半的公共数值,最后对所有符合条件的num求平均值就为题目所求的中位数。

①先求出以numbers为升序和降序时的总和;

1 SELECT number,
2        SUM(frequency) over(ORDER BY number) asc_accumu,
3        SUM(frequency) over(ORDER BY number DESC) desc_accumu
4 FROM numbers;

注意:numbers这一列最后是以第二个Sum中的order by 降序排序的,我实验了如果只有第一个sum则就是升序排序。

 ②求所有频率的总和;

1 SELECT SUM(frequency) total 
2 FROM numbers;

 ③加上where条件,要求正序和逆序是要大于等于总和的一半,在求出平均值即可。

 1 SELECT
 2     ROUND(AVG(b.number), 1 ) median 
 3 FROM
 4     (
 5     SELECT
 6         number,
 7         SUM( frequency ) over ( ORDER BY number ) asc_accumu,
 8         SUM( frequency ) over ( ORDER BY number DESC ) desc_accumu,
 9         SUM( frequency ) total 
10     FROM
11         numbers a
12     ) as b 
13 WHERE asc_accumu >= total/2 AND desc_accumu >= total/2;

小知识:

①中位数思路

 ②sum() over():

SELECT id,name,salary,
SUM(salary) over (PARTITION BY id ORDER BY name) AS a
FROM employee b;

说明:
1执行:"ORDER BY name" 按照name进行升序排序。
2执行:"sum(salary)" 对salary进行求和,
求和特点:第n行的和总是等于n-1加上n-2的和(如:第3行的和总是1和2行的和)。