用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。
根据魔术贴的答案,对于那些必须根据另一个参数分组的东西做中位数的人来说
SELECT grp_field, t1。val FROM (
SELECT grp_field, @rownum:=IF(@s = grp_field, @rownum + 1,0) AS row_number,
@s:=IF(@s = grp_field, @s, grp_field) AS sec, d.val
FROM data d, (SELECT @rownum:=0, @s:=0
ORDER BY grp_field, d.val
)作为t1 JOIN (
SELECT grp_field, count(*)为total_rows
数据d
GROUP BY grp_field
)为t2
在t1。Grp_field = t2.grp_field
在t1.row_number =地板(total_rows / 2) + 1;
上面的大多数解决方案只适用于表中的一个字段,您可能需要获得查询中多个字段的中位数(第50百分位数)。
我用这个:
SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(
GROUP_CONCAT(field_name ORDER BY field_name SEPARATOR ','),
',', 50/100 * COUNT(*) + 1), ',', -1) AS DECIMAL) AS `Median`
FROM table_name;
你可以将上面例子中的“50”替换为任何百分位数,这是非常有效的。
只要确保你有足够的内存给GROUP_CONCAT,你可以改变它:
SET group_concat_max_len = 10485760; #10MB max length
详情:http://web.performancerasta.com/metrics-tips-calculating-95th-99th-or-any-percentile-with-single-mysql-query/
在阅读了所有之前的内容后,它们与我的实际需求不匹配,所以我实现了自己的一个不需要任何过程或复杂的语句,只是我GROUP_CONCAT所有来自我想要获得MEDIAN的列的值,并应用COUNT DIV BY 2,我从列表中间提取值,就像下面的查询一样:
(POS是我想要获得其中位数的列的名称)
(query) SELECT
SUBSTRING_INDEX (
SUBSTRING_INDEX (
GROUP_CONCAT(pos ORDER BY CAST(pos AS SIGNED INTEGER) desc SEPARATOR ';')
, ';', COUNT(*)/2 )
, ';', -1 ) AS `pos_med`
FROM table_name
GROUP BY any_criterial
我希望这能对一些人有用,就像这个网站上的许多其他评论对我一样。