用MySQL计算中值的最简单方法是什么(希望不要太慢)?我用AVG(x)来计算平均值,但我很难找到一个简单的方法来计算中值.现在,我将把所有的行返回到PHP,进行排序,然后 Select 中间的行,但肯定有一些简单的方法可以在一个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

Mysql相关问答推荐

我需要为用户提供MySQL视图和存储的 routine ,但不是基础表

SQL:CAST与窗口函数组合导致语法错误

可以优化这个带有重复WHERE子句的查询吗?

根据名称将值从一个字段复制到不同记录的同一字段

MySQL 8.0 可以在 Select 语句中返回 JSON 对象数组吗?

是否可以使用以EXPLAIN EXTENDED ...开头的 SQL 语句修改数据?

如何找到每个user_id每个产品的买家类型数量?

Mysql时间序列数据的最小值和最大值

如何在 mysql 中获取 Day Wise 的平均值?

mySql 查询运行速度超慢

如何将内置的时间浏览器过滤器反映到 Grafana 中的 mysql 查询中?

由于长时间操作而断开连接后,我的 sql 查询是否继续执行?

按长度过滤 varbinary 字段

如何通过未知列中的唯一值有效地更新 MySQL 行

mysql 5.5;可以从记录中排除表吗?

SQL 中的双杠 (||) 是什么意思?

没有 JDBC 类型的方言映射:1111

将 Django DB 从 SQLite 迁移到 MySQL 的最佳方法是什么?

MySQL嵌套 Select 查询?

第 1 行的 CSV 输入中的列数无效错误