SQL查找中位数

时间:2017-10-24 10:02:44

标签: mysql sql median

我有一个包含499个正整数非整数N的列表,我想找到这些数字的中位数,我在下面:

SELECT (ROUND(N,4)) FROM TABLE ORDER BY N LIMIT 1 OFFSET ((COUNT(N)-1)/2);

我收到以下错误:

  第15行的

“ERROR 1064(42000):您的SQL语法出错;   检查与您的MySQL服务器版本对应的手册   正确的语法在第4行“((COUNT(N)-1)/ 2)'附近使用”

如果我将((COUNT(N)-1)/2)替换为 249 (其中的中位数将在排序表之后),则此方法有效,因此我无法使用((COUNT(N)-1)/2)。为什么是这样?我该怎么做才能找到中位数?

由于

2 个答案:

答案 0 :(得分:1)

唉,你不能在limit中包含表达式。您可以计算表中的行数,然后将其作为限制传递。

我通常会使用:

select avg(n)
from (select t.*, (@rn := @rn + 1) as rn
      from (select t.*
            from t
            order by n
           ) t cross join
           (select @rn := 0) params
     ) t
where 2 * rn in (@rn - 1, @rn, @rn + 1);

注意:

  • 最新版本的MySQL需要额外级别的子查询 - 参数并不总是与order by混合。
  • where适用于偶数行和奇数行。
  • 当行数为偶数时,avg()取中间点。

答案 1 :(得分:0)

这有点复杂,你需要创建一个与你的数据对齐的索引并在捕获之后

SELECT 
*
FROM
(SELECT 
    t.*, @rownum:=@rownum + 1 AS rank
FROM
    myTabel t, (SELECT @rownum:=0) r
ORDER BY ColumnToSort) AS B
WHERE
     B.rank = (SELECT 
             ROUND(COUNT(*) / 2, 0)
        FROM
             myTable)

基本上,您希望获得行号等于选择的一半的行。 MySql不支持任何返回此值的函数,因此您需要自己创建。这里有一个很好的参考资料(MySQL - Get row number on select

主要代码在这几行代码后面:

SELECT 
    t.*, @rownum:=@rownum + 1 AS rank
FROM
    myTabel t, (SELECT @rownum:=0) r
ORDER BY ColumnToSort