mysql - MySQL中按中位数的复杂排序

标签 mysql sorting median

示例表:

age | fruit | number_bought |
20  | apple | 3000000       |
20  | apple | 20            |
20  | apple | 60            |
20  | apple | 30            |
20  | apple | 50            |
20  | apple | 4             |
20  | banana| 40            |
30  | grape | 400           |
30  | grape | 450           |
30  | grape | 500           |

简单地列出一个特定年龄的人在该年龄购买了多少特定水果。

现在,我需要按“最受欢迎的水果”对这张表进行排序,并按年龄和水果分组。

这是棘手的部分,我想使用 MEDIAN 来计算受欢迎程度,而不仅仅是平均数。因为有些人可能很不正常(他可能是推销员),比如上面示例中的 3000000,而“平均 20 岁”的购买量要少得多,正如您从示例中看到的那样。

上表按流行度中位数排序应该是这样的:

age | fruit | median |
30  | grape | 450    |
20  | apple | 40     |
20  | banana| 40     |

现在,如果我简单地使用“平均”计算,20,苹果就会赢得人气,仅仅因为一个推销员。这就是我想使用中位数的原因。

最佳答案

当项目数量为偶数时(例如,测试数据中有 apple),常见的中值查询似乎很困难。

简单的方法是:-

SELECT y.age, x.fruit, AVG(x.number_bought) AS number_bought
from data x
INNER JOIN data y
ON x.age = y.age
AND x.fruit = y.fruit
GROUP BY y.age, x.fruit, x.number_bought
HAVING SUM(SIGN(1-SIGN(y.number_bought-x.number_bought))) = FLOOR((COUNT(*)+1)/2)
ORDER BY number_bought DESC;

这并不严格准确,因为它只是取中间一条之前的一条(即,6 条记录的中位数将是位置 3.5 的一条 - 这仅使用 FLOOR 并获得记录号 3)。

可能稍微更准确一点,当有偶数时,这将得到 2 条记录任一侧的平均值

SELECT age, fruit, AVG(number_bought) AS number_bought
FROM 
(
    SELECT y.age, x.fruit, AVG(x.number_bought) AS number_bought
    from data x
    INNER JOIN data y
    ON x.age = y.age
    AND x.fruit = y.fruit
    GROUP BY y.age, x.fruit, x.number_bought
    HAVING SUM(SIGN(1-SIGN(y.number_bought-x.number_bought))) = FLOOR((COUNT(*)+1)/2)
    OR SUM(SIGN(1-SIGN(y.number_bought-x.number_bought))) = CEIL((COUNT(*)+1)/2)
) Sub1
GROUP BY age, fruit
ORDER BY number_bought DESC;

SQL fiddle 在这里:-

http://www.sqlfiddle.com/#!2/f1b49/13

关于mysql - MySQL中按中位数的复杂排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23811994/

相关文章:

python - 如何使用 python 制作盒须图

c++ - 使用容器中的第 n_th 个元素,但使用另一个键

mysql - 将 MySQL 记录从数据库传输到数据库

c - 我的 C 程序出了什么问题?这是关于指针和选择排序的

python - 按第一个、第二个、第三个字符的字母顺序对索引进行排序

arrays - Julia 中多个数组的中位数

php - Laravel 忽略我的 PHP 设置并超时

php - codeigniter 内连接表语法

php - 如何将传入的电子邮件消息插入 mySQL 数据库?

java - 想要根据对象键对 map 进行排序