首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用MySQL计算中位数的简便方法

用MySQL计算中位数的简便方法
EN

Stack Overflow用户
提问于 2009-08-18 08:13:50
回答 35查看 299.1K关注 0票数 229

使用MySQL计算中值的最简单(希望不要太慢)方法是什么?我使用AVG(x)来求平均值,但我很难找到一种简单的方法来计算中位数。现在,我将所有行返回到PHP,进行排序,然后选择中间的行,但肯定有一些简单的方法可以在单个MySQL查询中完成这项工作。

示例数据:

代码语言:javascript
复制
id | val
--------
 1    4
 2    7
 3    2
 4    2
 5    9
 6    8
 7    3

val上排序会得到2 2 3 4 7 8 9,所以中位数应该是4,而不是SELECT AVG(val) == 5

EN

回答 35

Stack Overflow用户

回答已采纳

发布于 2011-09-01 05:53:37

在MariaDB /MySQL中:

代码语言:javascript
复制
SELECT AVG(dd.val) as median_val
FROM (
SELECT d.val, @rownum:=@rownum+1 as `row_number`, @total_rows:=@rownum
  FROM data d, (SELECT @rownum:=0) r
  WHERE d.val is NOT NULL
  -- put some where clause here
  ORDER BY d.val
) as dd
WHERE dd.row_number IN ( FLOOR((@total_rows+1)/2), FLOOR((@total_rows+2)/2) );

Steve Cohen指出,在第一次传递之后,@rownum将包含总行数。这可以用来确定中位数,因此不需要第二次传递或连接。

此外,当有偶数条记录时,AVG(dd.val)dd.row_number IN(...)用于正确地产生中位数。推理:

代码语言:javascript
复制
SELECT FLOOR((3+1)/2),FLOOR((3+2)/2); -- when total_rows is 3, avg rows 2 and 2
SELECT FLOOR((4+1)/2),FLOOR((4+2)/2); -- when total_rows is 4, avg rows 2 and 3

最后,MariaDB 10.3.3+ contains a MEDIAN function

票数 249
EN

Stack Overflow用户

发布于 2012-06-04 14:59:33

我发现被接受的解决方案在我的MySQL安装上不起作用,返回一个空集,但是这个查询在我测试它的所有情况下都有效:

代码语言:javascript
复制
SELECT x.val from data x, data y
GROUP BY x.val
HAVING SUM(SIGN(1-SIGN(y.val-x.val)))/COUNT(*) > .5
LIMIT 1
票数 35
EN

Stack Overflow用户

发布于 2011-05-31 08:05:21

我提出了一种更快的方法。

获取行数:

SELECT CEIL(COUNT(*)/2) FROM data;

然后取排序后的子查询中的中间值:

SELECT max(val) FROM (SELECT val FROM data ORDER BY val limit @middlevalue) x;

我用一个5x10e6的随机数数据集进行了测试,它将在10秒内找到中位数。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1291152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档