Numbers
表保留数字的值及其频率。
+----------+-------------+
| Number | Frequency |
+----------+-------------|
| 0 | 7 |
| 1 | 1 |
| 2 | 3 |
| 3 | 1 |
+----------+-------------+
在此表中,数字为0、0、0、0、0、0、0、1、2、2、2、3,因此中位数为(0 + 0)/ 2 = 0。找到给定数字频率的中位数(显示输出)?
+--------+
| median |
+--------|
| 0.0000 |
+--------+
我找到了以下解决方案here。但是,我无法理解。有人可以解释一下解决方案和/或发布带有解释的其他解决方案吗?
SELECT AVG(n.Number) AS median
FROM Numbers n LEFT JOIN
(
SELECT Number, @prev := @count AS prevNumber, (@count := @count + Frequency) AS countNumber
FROM Numbers,
(SELECT @count := 0, @prev := 0, @total := (SELECT SUM(Frequency) FROM Numbers)) temp ORDER BY Number
) n2
ON n.Number = n2.Number
WHERE
(prevNumber < floor((@total+1)/2) AND countNumber >= floor((@total+1)/2))
OR
(prevNumber < floor((@total+2)/2) AND countNumber >= floor((@total+2)/2))
以下是可重复性的SQL脚本:
CREATE TABLE `Numbers` (
`Number` INT NULL,
`Frequency` INT NULL);
INSERT INTO `Numbers` (`Number`, `Frequency`) VALUES ('0', '7');
INSERT INTO `Numbers` (`Number`, `Frequency`) VALUES ('1', '1');
INSERT INTO `Numbers` (`Number`, `Frequency`) VALUES ('2', '3');
INSERT INTO `Numbers` (`Number`, `Frequency`) VALUES ('3', '1');
谢谢!
答案 0 :(得分:0)
您可以使用累加和,然后取中点。我认为逻辑看起来像这样:
select avg(number)
from (select t.*, (@rf := @rf + frequency) as running_frequency
from (select t.* from t order by number) t cross join
(select @rf := 0) params
) t
where running_frequency - frequency >= ceil(@rf / 2) and
running_frequency <= ceil((@rf + 1) / 2);