用Mysql计算中位数

| 我在计算值列表的中位数而不是平均值时遇到了麻烦。 我发现这篇文章 用MySQL计算中位数的简单方法 它引用了以下我不正确理解的查询。
SELECT x.val from data x, data y
GROUP BY x.val
HAVING SUM(SIGN(1-SIGN(y.val-x.val))) = (COUNT(*)+1)/2
如果我有一个
time
列,并且想要计算中位数,那么
x
y
列指的是什么?     
已邀请:
        time4ѭ是您的时间列,
x
y
是数据表的两个引用(您可以写
data AS x, data AS y
)。 编辑: 为避免两次计算总和,可以存储中间结果。
CREATE TEMPORARY TABLE average_user_total_time 
      (SELECT SUM(time) AS time_taken 
            FROM scores 
            WHERE created_at >= \'2010-10-10\' 
                    and created_at <= \'2010-11-11\' 
            GROUP BY user_id);
然后,您可以计算命名表中这些值的中位数。 编辑:临时表将无法在这里工作。您可以尝试使用具有\“ MEMORY \”表类型的常规表。或者只是让您的子查询在查询中两次计算中值。除此之外,我没有看到其他解决方案。这并不意味着没有更好的方法,也许其他人会想到一个主意。     
        我提出了一种更快的方法。 获取行数:
SELECT CEIL(COUNT(*)/2) FROM data;
然后将中间值带入已排序的子查询中:
SELECT max(val) FROM (SELECT val FROM data ORDER BY val limit @middlevalue) x;
我使用5x10e6随机数数据集对此进行了测试,它将在10秒内找到中值。 通过将ѭ11替换为ѭ12将找到一个任意的百分位数,其中
n
是百分位数(中位数为.5,第75个百分位数为.75,等等)。     
        首先尝试了解中位数是什么:中位数是值排序列表中的中间值。 了解这一点后,方法就是两个步骤: 按任一顺序对值进行排序 选择中间值(如果不是奇数个值,则选择两个中间值的平均值) 例:
Median of 0 1 3 7 9 10: 5 (because (7+3)/2=5)
Median of 0 1 3 7 9 10 11: 7 (because 7 is the middle value)
因此,要对日期进行排序,您需要一个数值;您可以获取其时间戳记(从纪元开始经过的秒数)并使用中位数的定义。     
        使用group_concat在mysql中查找中位数 查询:
SELECT
    IF(count%2=1,
       SUBSTRING_INDEX(substring_index(data_str,\",\",pos),\",\",-1),
       (SUBSTRING_INDEX(substring_index(data_str,\",\",pos),\",\",-1) 
         + SUBSTRING_INDEX(substring_index(data_str,\",\",pos+1),\",\",-1))/2) 
    as median 
FROM (SELECT group_concat(val order by val) data_str,
      CEILING(count(*)/2) pos,
      count(*) as count from data)temp;
说明: 通过group_concat函数内部的顺序进行排序 确定位置(pos)和元素总数(计数)。通过天花板确定位置可以帮助我们在以下步骤中使用substring_index函数。 基于计数,确定值的偶数或奇数。 奇数值:使用substring_index直接选择属于pos的元素。 偶数:找到属于pos和pos + 1的元素,然后将它们相加并除以2得到中位数。 最终计算出中位数。     
        如果您的表
R
的列名为
A
,并且想要A的中位数,则可以执行以下操作:
SELECT A FROM R R1
WHERE ( SELECT COUNT(A) FROM R R2 WHERE R2.A < R1.A ) = ( SELECT COUNT(A) FROM R R3 WHERE R3.A > R1.A )
注意:仅当A中没有重复的值时,此方法才有效。而且,不允许使用空值。     
        我和我的朋友发现问题的最简单方法就是……享受!
SELECT count(*) INTO @c from station;
select ROUND((@c+1)/2) into @final; 
SELECT round(lat_n,4) from station a where @final-1=(select count(lat_n) from station b where b.lat_n > a.lat_n);
    
        这是一个易于理解的解决方案。只需根据需要替换Your_Column和Your_Table。
SET @r = 0;

SELECT AVG(Your_Column)
FROM (SELECT (@r := @r + 1) AS r, Your_Column FROM Your_Table ORDER BY Your_Column) Temp
WHERE
    r = (SELECT CEIL(COUNT(*) / 2) FROM Your_Table) OR
    r = (SELECT FLOOR((COUNT(*) / 2) + 1) FROM Your_Table)
最初从此线程采用。     

要回复问题请先登录注册