sql - 用MySQL计算中位数的简单方法

标签 sql mysql statistics median

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

示例数据:

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

最佳答案

在 MariaDB/MySQL 中:

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(...) 用于在存在偶数条记录时正确生成中位数。推理:

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

关于sql - 用MySQL计算中位数的简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56964116/

相关文章:

sql - View 比简单查询更快吗?

php - 如何在不刷新页面的情况下显示错误?

php - MYSQL 两个不同表查询相同字段

r - 在 R 中使用 Gram-Schmidt 正交化进行特征选择

c# - 我在这里找平均水平吗

mysql - 将 Excel 公式转换为 MySQL 查询

mysql - 在 MYSQL 中捕获错误

javascript - Nodejs + SocketIO + MySql 连接未正确关闭并创建数据库开销

php - 如何使用 **TIME ZONE** 将 NSDate 存储到 DATETIME?

c - 在 Linux 中测量进程统计信息