用MySQL计算中位数的简单方法
用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
。
建议的解决方案(TheJacobTaylor)的问题是运行时问题。 加入表格本身对于大型数据集来说太慢了。 我建议的替代方案在MySQL中运行,运行时非常棒,使用显式的ORDER BY语句,因此您不必希望索引为了给出正确的结果而正确命令它,并且很容易展开查询以进行调试。
SELECT avg(t1.val) as median_val FROM (
SELECT @rownum:=@rownum+1 as `row_number`, d.val
FROM data d, (SELECT @rownum:=0) r
WHERE 1
-- put some where clause here
ORDER BY d.val
) as t1,
(
SELECT count(*) as total_rows
FROM data d
WHERE 1
-- put same where clause here
) as t2
WHERE 1
AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) );
[edit]在(...)中添加avg()周围的t1.val和row_number,以便在存在偶数个记录时正确生成中位数。 推理:
SELECT floor((3+1)/2),floor((3+2)/2);#total_rows is 3, so avg row_numbers 2 and 2
SELECT floor((4+1)/2),floor((4+2)/2);#total_rows is 4, so avg row_numbers 2 and 3
我刚刚在评论中发现了另一个在线答案:
对于几乎任何SQL中的中值:
SELECT x.val from data x, data y
GROUP BY x.val
HAVING SUM(SIGN(1-SIGN(y.val-x.val))) = (COUNT(*)+1)/2
确保您的列的索引很好,并且索引用于过滤和排序。 验证解释计划。
select count(*) from table --find the number of rows
计算“中位数”行号。 也许使用: median_row = floor(count / 2)
。
然后从列表中选择它:
select val from table order by val asc limit median_row,1
这应该返回你一行,只是你想要的值。
雅各
我发现接受的解决方案不适用于我的MySQL安装,返回一个空集,但是这个查询在我测试过的所有情况下都适用于我:
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
链接地址: http://www.djcxy.com/p/83819.html
上一篇: Simple way to calculate median with MySQL
下一篇: binding with 'with'?