通过GROUP_CONCAT将结果排序后组成逗号分割的新字符串, 并通过SUBSTRING_INDEX, 获取到总量/2的结果,再通过SUBSTIRNG_INDEX -1的获取倒数第一个值,即为中位数结果。
那么如果加上案例来源获取中位数,这代码会变成什么样?
SELECT CaseFrom,SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(Price ORDER BY Price),',',Count(1)/2),',',-1) zws
FROM CaseRent WHERE ResidentialAreaID = 99 Group By CaseFrom;
再加上区分小区呢?:
SELECT ResidentialAreaID,CaseFrom,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(Price ORDER BY Price),',',Count(1)/2),',',-1) zws
FROM CaseRent Group By ResidentialAreaID,CaseFrom;
似乎很简单,但是GROUP_CONCAT有个默认承载长度 1024
如果不修改参数的情况下,做大量数据的中位数统计,会超出GROUP_CONCAT的承载长度,导致计算错误。
而一般情况下,我们无法修改服务器的Mysql配参,可以通过:
show variables like 'group_concat_max_len'
来参考当前参数。
以及:
-- 以当前会话,临时修改GROUP_CONCAT支撑长度。
SET @@GROUP_CONCAT_MAX_LEN = 1024000;
当然,如果有必要,可以直接通知运维修改一下参数长度,如果不常用,可以自行使用这种方式修改后临时使用;因此数据量大的情况下,正确的写法如下:
复制代码
SET @@GROUP_CONCAT_MAX_LEN = 1024000;
SELECT ResidentialAreaID,CaseFrom,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(Price ORDER BY Price),',',Count(1)/2),',',-1) zws
FROM CaseRent Group By ResidentialAreaID,CaseFrom;
到此,中位数算法结束。
主要知识点:
临时变量
临时表